0001: /**********************************************************************************
0002: * $URL: https://source.sakaiproject.org/svn/portal/trunk/portal-util/util/src/java/org/sakaiproject/portal/util/PortalSiteHelper.java $
0003: * $Id: PortalSiteHelper.java 21708 2007-02-18 21:59:28Z ian@caret.cam.ac.uk $
0004: ***********************************************************************************
0005: *
0006: * Copyright (c) 2007 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.chat2.tool;
0021:
0022: import java.io.IOException;
0023: import java.text.MessageFormat;
0024: import java.util.ArrayList;
0025: import java.util.Date;
0026: import java.util.Iterator;
0027: import java.util.List;
0028:
0029: import javax.faces.application.FacesMessage;
0030: import javax.faces.context.ExternalContext;
0031: import javax.faces.context.FacesContext;
0032: import javax.faces.model.SelectItem;
0033:
0034: import org.apache.commons.logging.Log;
0035: import org.apache.commons.logging.LogFactory;
0036: import org.sakaiproject.authz.api.PermissionsHelper;
0037: import org.sakaiproject.chat2.model.ChatMessage;
0038: import org.sakaiproject.chat2.model.ChatChannel;
0039: import org.sakaiproject.chat2.model.ChatManager;
0040: import org.sakaiproject.chat2.model.RoomObserver;
0041: import org.sakaiproject.chat2.model.ChatFunctions;
0042: import org.sakaiproject.chat2.model.PresenceObserver;
0043: import org.sakaiproject.component.cover.ServerConfigurationService;
0044: import org.sakaiproject.courier.api.CourierService;
0045: import org.sakaiproject.exception.IdUnusedException;
0046: import org.sakaiproject.exception.PermissionException;
0047: import org.sakaiproject.site.api.Site;
0048: import org.sakaiproject.site.cover.SiteService;
0049: import org.sakaiproject.tool.api.Placement;
0050: import org.sakaiproject.tool.api.Session;
0051: import org.sakaiproject.tool.api.ToolManager;
0052: import org.sakaiproject.tool.cover.SessionManager;
0053: import org.sakaiproject.user.api.User;
0054: import org.sakaiproject.user.api.UserNotDefinedException;
0055: import org.sakaiproject.user.cover.UserDirectoryService;
0056: import org.sakaiproject.util.DirectRefreshDelivery;
0057: import org.sakaiproject.util.ResourceLoader;
0058: import org.sakaiproject.util.Validator;
0059:
0060: /**
0061: * Chat works by the courier but not the same way as the old message delivery
0062: * system. The courier sends messages into the JSF tool. When the user dials home
0063: * it then picks up the messages.
0064: *
0065: * COOL TECHNOLOGY ALERT:
0066: * TODO: The page that sends the messages is polled, the tool can wait on the
0067: * connection until it recieves a message to send or until it times out. This
0068: * would provide instant messaging as opposed to polling.
0069: *
0070: * When entering the tool the first main page calls the enterTool function which
0071: * redirects the users based upon the tool's preferences: go to select a room or
0072: * to a specific tool.
0073: *
0074: * The PresenceObserverHelper is placed on the current room. This this tool is informed
0075: * when a user enters and exits the room. If the tool is forgotten (user clicked
0076: * the tool refresh button or closed the browser) then eventually the presence service
0077: * will remove that user from the location... which we are informed. The problem is
0078: * that the presence change event doesn't say WHO entered or exited. Thus... we must wait
0079: * until there are no users in the location before we know that we shouldn't be observing
0080: *
0081: *
0082: * @author andersjb
0083: *
0084: */
0085: public class ChatTool implements RoomObserver, PresenceObserver {
0086:
0087: /** Our logger. */
0088: private static Log logger = LogFactory.getLog(ChatTool.class);
0089:
0090: /* */
0091: private static final String IFRAME_ROOM_USERS = "Presence";
0092:
0093: /* various pages that we can go to within the tool */
0094: private static final String PAGE_EDIT_A_ROOM = "editRoom";
0095: private static final String PAGE_LIST_ROOMS = "listRooms";
0096: private static final String PAGE_ENTER_ROOM = "room";
0097: private static final String PAGE_ROOM_CONTROL = "roomControl";
0098: private static final String PAGE_EDIT_ROOM = "editRoom";
0099: private static final String PAGE_DELETE_ROOM_CONFIRM = "deleteRoomConfirm";
0100: private static final String PAGE_DELETE_MESSAGE_CONFIRM = "deleteMessageConfirm";
0101: private static final String PAGE_SYNOPTIC = "synoptic";
0102: private static final String PAGE_SYNOPTIC_OPTIONS = "synopticOptions";
0103:
0104: private static final String PERMISSION_ERROR = "perm_error";
0105: private static final String PRESENCE_PREPEND = "chat_room_";
0106:
0107: private static final int MESSAGEOPTIONS_NULL = -99;
0108: private static final int MESSAGEOPTIONS_ALL_MESSAGES = -1;
0109: private static final int MESSAGEOPTIONS_MESSAGES_BY_DATE = 0;
0110: private static final int MESSAGEOPTIONS_MESSAGES_BY_NUMBER = 1;
0111:
0112: private static final int DATETIME_DISPLAY_NONE = 0;
0113: private static final int DATETIME_DISPLAY_TIME = 1;
0114: private static final int DATETIME_DISPLAY_DATE = 2;
0115: private static final int DATETIME_DISPLAY_DATETIME = 3;
0116:
0117: private static final String PARAM_CHANNEL = "channel";
0118: private static final String PARAM_DAYS = "days";
0119: private static final String PARAM_ITEMS = "items";
0120: private static final String PARAM_LENGTH = "length";
0121:
0122: private static final int DEFAULT_DAYS = 10;
0123: private static final int DEFAULT_ITEMS = 3;
0124: private static final int DEFAULT_LENGTH = 50;
0125:
0126: /* All the managers */
0127: /** The work-horse of chat */
0128: private ChatManager chatManager;
0129:
0130: /** The tool manager */
0131: private ToolManager toolManager;
0132:
0133: /** Constructor discovered injected CourierService. */
0134: protected CourierService m_courierService = null;
0135:
0136: /* All the private variables */
0137: /** The current channel the user is in */
0138: private DecoratedChatChannel currentChannel = null;
0139:
0140: /** The current channel the user is editing */
0141: private DecoratedChatChannel currentChannelEdit = null;
0142:
0143: /** The current message the user is deleting */
0144: private DecoratedChatMessage currentMessage = null;
0145:
0146: private DecoratedSynopticOptions currentSynopticOptions = null;
0147:
0148: /** The location where the new message text goes */
0149: private String newMessageText = "";
0150:
0151: /** display the time (1), date(2), both(3), or neither(0) */
0152: private int viewOptions = DATETIME_DISPLAY_DATETIME;
0153:
0154: /** display all messages (-1), past 3 days (0) */
0155: private int messageOptions = MESSAGEOPTIONS_NULL;
0156:
0157: /** The id of the session. needed for adding messages to the courier because that runs in the notification thread */
0158: private String sessionId = "";
0159:
0160: /** The id of the placement of this sakai tool. the jsf tool bean needs this for passing to the delivery */
0161: private String placementId = "";
0162:
0163: /** Mapping the color of each message */
0164: private ColorMapper colorMapper = new ColorMapper();
0165:
0166: /** the worksite the tool is in */
0167: private Site worksite = null;
0168:
0169: /* error conditions */
0170: /** an error that could display on the select a chat room page */
0171: private boolean selectedRoomNotAvailable = false;
0172:
0173: /** Allows us to see who is in the current room */
0174: private PresenceObserverHelper presenceChannelObserver = null;
0175:
0176: /**
0177: * This is called from the first page to redirect the user to the proper view.
0178: * If the tool is set to go to the select a chat room view and there are multiple chat
0179: * rooms, then it will go to the select a room page. If the user is to select a room and
0180: * there is only one room, then it will go to that room.
0181: *
0182: * @return String
0183: */
0184: public String getEnterTool() {
0185:
0186: // "inject" a CourierService
0187: m_courierService = org.sakaiproject.courier.cover.CourierService
0188: .getInstance();
0189:
0190: Session session = SessionManager.getCurrentSession();
0191:
0192: sessionId = session.getId();
0193: String url = PAGE_ENTER_ROOM;
0194:
0195: Placement placement = getToolManager().getCurrentPlacement();
0196: placementId = placement.getId();
0197:
0198: //Really onl calling this just to make sure a room gets created
0199: List rooms = getSiteChannels();
0200:
0201: ChatChannel defaultChannel = getChatManager()
0202: .getDefaultChannel(placement.getContext());
0203: setCurrentChannel(new DecoratedChatChannel(this , defaultChannel));
0204:
0205: // if there is no room selected to enter then go to select a room
0206: if (currentChannel == null)
0207: url = PAGE_LIST_ROOMS;
0208:
0209: ExternalContext context = FacesContext.getCurrentInstance()
0210: .getExternalContext();
0211:
0212: try {
0213: context.redirect(url);
0214: } catch (IOException e) {
0215: throw new RuntimeException("Failed to redirect to " + url,
0216: e);
0217: }
0218: return "";
0219: }
0220:
0221: /**
0222: * this gets the users in the current channel. It should be called often
0223: * to refresh the presence of the channel
0224: * @return List of Sakai User(?)
0225: */
0226: public List getUsersInCurrentChannel() {
0227: if (!refreshPresence()) {
0228: return new ArrayList();
0229: }
0230:
0231: presenceChannelObserver.updatePresence();
0232:
0233: // put into context a list of sessions with chat presence
0234: String location = presenceChannelObserver.getLocation();
0235:
0236: // get the current presence list (User objects) for this page
0237: List users = presenceChannelObserver.getPresentUsers();
0238:
0239: return users;
0240: }
0241:
0242: protected boolean refreshPresence() {
0243: if (getCurrentChannel() == null) {
0244: ChatChannel defaultChannel = getChatManager()
0245: .getDefaultChannel(
0246: getToolManager().getCurrentPlacement()
0247: .getContext());
0248: setCurrentChannel(new DecoratedChatChannel(this ,
0249: defaultChannel));
0250: }
0251: if (getCurrentChannel() != null) {
0252: // place a presence observer on this tool.
0253: presenceChannelObserver = new PresenceObserverHelper(this ,
0254: getCurrentChannel().getChatChannel().getId());
0255:
0256: getChatManager().addRoomListener(this ,
0257: getCurrentChannel().getChatChannel().getId());
0258: return true;
0259: //presenceChannelObserver.updatePresence();
0260: }
0261: return false;
0262: }
0263:
0264: //********************************************************************
0265: // Interface Implementations
0266:
0267: /**
0268: * {@inheritDoc}
0269: * in the context of the event manager thread
0270: */
0271: public void receivedMessage(String roomId, Object message) {
0272: if (currentChannel != null
0273: && currentChannel.getChatChannel().getId().equals(
0274: roomId)) {
0275: m_courierService.deliver(new ChatDelivery(sessionId
0276: + roomId, "Monitor", message, placementId, false,
0277: getChatManager()));
0278: }
0279: }
0280:
0281: /**
0282: * {@inheritDoc}
0283: */
0284: public void roomDeleted(String roomId) {
0285: if (currentChannel != null
0286: && currentChannel.getChatChannel().getId().equals(
0287: roomId)) {
0288: resetCurrentChannel(currentChannel);
0289: }
0290: }
0291:
0292: /**
0293: * {@inheritDoc}
0294: */
0295: public void userJoined(String location, String user) {
0296: m_courierService.deliver(new DirectRefreshDelivery(sessionId
0297: + location, "Presence"));
0298: }
0299:
0300: /**
0301: * {@inheritDoc}
0302: * If a user left the location and there are no more users then
0303: * something happened and this is a stray presence observer. When there
0304: * are no users in a presence then the observer should be removed because
0305: * this tool isn't updating the presence any longer thus isn't in the location
0306: * thus doesn't need to observe the presence of the room.
0307: */
0308: public void userLeft(String location, String user) {
0309: if (presenceChannelObserver != null
0310: && presenceChannelObserver.getPresentUsers().size() == 0) {
0311: presenceChannelObserver.endObservation();
0312: getChatManager().removeRoomListener(this ,
0313: currentChannel.getChatChannel().getId());
0314: presenceChannelObserver = null;
0315: } else
0316: m_courierService.deliver(new DirectRefreshDelivery(
0317: sessionId + location, "Presence"));
0318: }
0319:
0320: //********************************************************************
0321: // Tool Process Actions
0322:
0323: /**
0324: * resets various variables for the tool
0325: */
0326: private void clearToolVars() {
0327: selectedRoomNotAvailable = false;
0328: }
0329:
0330: /**
0331: * Make sure that the channel has a title when saving
0332: * @param channel
0333: * @return Returns if the channel validates
0334: */
0335: protected boolean validateChannel(ChatChannel channel) {
0336: if (channel.getTitle() == null
0337: || channel.getTitle().length() == 0) {
0338:
0339: setErrorMessage("title_required", new String[] {});
0340: return false;
0341: }
0342:
0343: else
0344: return true;
0345: }
0346:
0347: /**
0348: * When the user wants to cancel changing a room
0349: * @return String next page
0350: */
0351: public String processActionCancelChangeChannel() {
0352: clearToolVars();
0353:
0354: return PAGE_ENTER_ROOM;
0355: }
0356:
0357: public String processActionSetAsDefaultRoom(
0358: DecoratedChatChannel decoChannel) {
0359: ChatChannel channel = decoChannel.getChatChannel();
0360: channel.setContextDefaultChannel(true);
0361: getChatManager().makeDefaultContextChannel(channel);
0362: return PAGE_LIST_ROOMS;
0363: }
0364:
0365: public String processActionAddRoom() {
0366: try {
0367: ChatChannel newChannel = getChatManager().createNewChannel(
0368: getContext(), "", false, true);
0369: currentChannelEdit = new DecoratedChatChannel(this ,
0370: newChannel, true);
0371:
0372: //init the filter param
0373: if (currentChannelEdit.getChatChannel().getFilterType()
0374: .equals(ChatChannel.FILTER_BY_NUMBER)
0375: || currentChannelEdit.getChatChannel()
0376: .getFilterType().equals(
0377: ChatChannel.FILTER_BY_TIME)) {
0378: currentChannelEdit
0379: .setFilterParamLast(currentChannelEdit
0380: .getChatChannel().getFilterParam());
0381: currentChannelEdit
0382: .setFilterParamPast(currentChannelEdit
0383: .getChatChannel().getFilterParam());
0384: }
0385: //return "";
0386: return PAGE_EDIT_A_ROOM;
0387: } catch (PermissionException e) {
0388: setErrorMessage(
0389: PERMISSION_ERROR,
0390: new String[] { ChatFunctions.CHAT_FUNCTION_NEW_CHANNEL });
0391: return "";
0392: }
0393: }
0394:
0395: public String processActionSubmitMessage() {
0396: try {
0397: ChatMessage message = getChatManager().createNewMessage(
0398: getCurrentChannel().getChatChannel(),
0399: SessionManager.getCurrentSessionUserId());
0400: message.setBody(newMessageText);
0401: if (!newMessageText.equals("")) {
0402: newMessageText = "";
0403: getChatManager().updateMessage(message);
0404: getChatManager().sendMessage(message);
0405: }
0406: return PAGE_ROOM_CONTROL;
0407: } catch (PermissionException e) {
0408: setErrorMessage(PERMISSION_ERROR,
0409: new String[] { ChatFunctions.CHAT_FUNCTION_NEW });
0410: return "";
0411: }
0412: }
0413:
0414: public String processActionResetMessage() {
0415: newMessageText = "";
0416: return PAGE_ROOM_CONTROL;
0417: }
0418:
0419: public String processActionPermissions() {
0420: ExternalContext context = FacesContext.getCurrentInstance()
0421: .getExternalContext();
0422:
0423: try {
0424: String url = "sakai.permissions.helper.helper/tool?"
0425: + "session." + PermissionsHelper.DESCRIPTION + "="
0426: + getPermissionsMessage() + "&session."
0427: + PermissionsHelper.TARGET_REF + "="
0428: + getWorksite().getReference() + "&session."
0429: + PermissionsHelper.PREFIX + "="
0430: + getChatFunctionPrefix();
0431:
0432: context.redirect(url);
0433: } catch (IOException e) {
0434: throw new RuntimeException("Failed to redirect to helper",
0435: e);
0436: }
0437: return null;
0438: }
0439:
0440: public String processActionSynopticOptions() {
0441: DecoratedSynopticOptions dso = lookupSynopticOptions();
0442: setCurrentSynopticOptions(dso);
0443: return PAGE_SYNOPTIC_OPTIONS;
0444: }
0445:
0446: public String processActionSynopticOptionsSave() {
0447: DecoratedSynopticOptions dso = getCurrentSynopticOptions();
0448:
0449: Placement placement = getToolManager().getCurrentPlacement();
0450: if (placement != null) {
0451: //placement.getPlacementConfig().setProperty(PARAM_CHANNEL, (String) state.getAttribute(STATE_CHANNEL_REF));
0452: placement.getPlacementConfig().setProperty(PARAM_DAYS,
0453: Integer.toString(dso.getDays()));
0454: placement.getPlacementConfig().setProperty(PARAM_ITEMS,
0455: Integer.toString(dso.getItems()));
0456: placement.getPlacementConfig().setProperty(PARAM_LENGTH,
0457: Integer.toString(dso.getChars()));
0458: placement.save();
0459: }
0460: setCurrentSynopticOptions(null);
0461: return PAGE_SYNOPTIC;
0462: }
0463:
0464: public String processActionSynopticOptionsCancel() {
0465: setCurrentSynopticOptions(null);
0466: return PAGE_SYNOPTIC;
0467: }
0468:
0469: public String processActionBackToRoom() {
0470: return PAGE_ENTER_ROOM;
0471: }
0472:
0473: public String getChatFunctionPrefix() {
0474: return ChatFunctions.CHAT_FUNCTION_PREFIX;
0475: }
0476:
0477: public String getPermissionsMessage() {
0478: return getMessageFromBundle("perm_description", new Object[] {
0479: getToolManager().getCurrentTool().getTitle(),
0480: getWorksite().getTitle() });
0481: }
0482:
0483: public Site getWorksite() {
0484: if (worksite == null) {
0485: try {
0486: worksite = SiteService.getSite(getToolManager()
0487: .getCurrentPlacement().getContext());
0488: } catch (IdUnusedException e) {
0489: throw new RuntimeException(e);
0490: }
0491: }
0492: return worksite;
0493: }
0494:
0495: //********************************************************************
0496: // Channel Process Actions
0497:
0498: /**
0499: * Sets the current room and goes to the room page
0500: * @param chatChannel
0501: * @return String selects a new room to go into
0502: */
0503: protected String processActionEnterRoom(
0504: DecoratedChatChannel chatChannel) {
0505: setCurrentChannel(chatChannel);
0506: return PAGE_ENTER_ROOM;
0507: }
0508:
0509: public String processActionListRooms() {
0510: return PAGE_LIST_ROOMS;
0511: }
0512:
0513: /**
0514: * Sets the current room and goes to edit that room
0515: * @param chatChannel
0516: * @return String goes to the edit room view
0517: */
0518: protected String processActionEditRoom(
0519: DecoratedChatChannel chatChannel) {
0520: //Init the filter param here
0521: if (chatChannel.getChatChannel().getFilterType().equals(
0522: ChatChannel.FILTER_BY_NUMBER)
0523: || chatChannel.getChatChannel().getFilterType().equals(
0524: ChatChannel.FILTER_BY_TIME)) {
0525: chatChannel.setFilterParamLast(chatChannel.getChatChannel()
0526: .getFilterParam());
0527: chatChannel.setFilterParamPast(chatChannel.getChatChannel()
0528: .getFilterParam());
0529: }
0530:
0531: setCurrentChannelEdit(chatChannel);
0532: return PAGE_EDIT_ROOM;
0533: }
0534:
0535: /**
0536: * Sets the current room to null
0537: * @return String goes to the edit room view
0538: */
0539: public String processActionEditRoomSave() {
0540: //Set the filter param here
0541: ChatChannel channel = getCurrentChannelEdit().getChatChannel();
0542: boolean directEdit = getCurrentChannelEdit().isDirectEdit();
0543:
0544: if (channel.getFilterType()
0545: .equals(ChatChannel.FILTER_BY_NUMBER)) {
0546: channel.setFilterParam(getCurrentChannelEdit()
0547: .getFilterParamLast());
0548: } else if (channel.getFilterType().equals(
0549: ChatChannel.FILTER_BY_TIME)) {
0550: channel.setFilterParam(getCurrentChannelEdit()
0551: .getFilterParamPast());
0552: }
0553: String retView = PAGE_LIST_ROOMS;
0554:
0555: if (directEdit)
0556: retView = PAGE_ENTER_ROOM;
0557: else
0558: retView = PAGE_LIST_ROOMS;
0559:
0560: if (validateChannel(channel))
0561: try {
0562: getChatManager().updateChannel(channel, true);
0563:
0564: if (getCurrentChannel().getChatChannel().getId()
0565: .equals(channel.getId())) {
0566: setCurrentChannel(new DecoratedChatChannel(this ,
0567: channel));
0568: }
0569: //setCurrentChannel(channel);
0570: setCurrentChannelEdit(null);
0571:
0572: } catch (PermissionException e) {
0573: setErrorMessage(
0574: PERMISSION_ERROR,
0575: new String[] { ChatFunctions.CHAT_FUNCTION_EDIT_CHANNEL });
0576: return "";
0577: }
0578: else {
0579: //Message should get set in the validateChannel method
0580: //setErrorMessage(VALIDATION_ERROR, new String[] {ChatFunctions.CHAT_FUNCTION_DELETE_PREFIX});
0581: retView = "";
0582: }
0583: return retView;
0584: }
0585:
0586: /**
0587: * Sets the current room to null
0588: * @return String goes to the edit room view
0589: */
0590: public String processActionEditRoomCancel() {
0591: boolean directEdit = getCurrentChannelEdit().isDirectEdit();
0592: setCurrentChannelEdit(null);
0593:
0594: if (directEdit)
0595: return PAGE_ENTER_ROOM;
0596: else
0597: return PAGE_LIST_ROOMS;
0598:
0599: }
0600:
0601: /**
0602: * Sets the current room and goes to confirm deleting the room
0603: * @param chatChannel
0604: * @return String goes to the delete room confirmation page
0605: */
0606: protected String processActionDeleteRoomConfirm(
0607: DecoratedChatChannel chatChannel) {
0608: setCurrentChannelEdit(chatChannel);
0609: return PAGE_DELETE_ROOM_CONFIRM;
0610: }
0611:
0612: /**
0613: * deletes the current room and all it's messages
0614: * @return String goes to the select a room page
0615: */
0616: public String processActionDeleteRoom() {
0617: try {
0618: getChatManager().deleteChannel(
0619: currentChannelEdit.getChatChannel());
0620: setCurrentChannelEdit(null);
0621: return PAGE_LIST_ROOMS;
0622: } catch (PermissionException e) {
0623: setErrorMessage(
0624: PERMISSION_ERROR,
0625: new String[] { ChatFunctions.CHAT_FUNCTION_DELETE_CHANNEL });
0626: return "";
0627: }
0628: }
0629:
0630: /**
0631: * cancels the deletion of a room via the confirmation
0632: * @return String goes to the select a room page
0633: */
0634: public String processActionDeleteRoomCancel() {
0635: setCurrentChannelEdit(null);
0636: return PAGE_LIST_ROOMS;
0637: }
0638:
0639: // ********************************************************************
0640: // Message Process Actions
0641:
0642: /**
0643: * Deletes the current message
0644: * @return String goes to the room's main page
0645: */
0646: public String processActionDeleteMessage() {
0647: try {
0648: getChatManager().deleteMessage(
0649: getCurrentMessage().getChatMessage());
0650: return PAGE_ENTER_ROOM;
0651: } catch (PermissionException e) {
0652: setErrorMessage(
0653: PERMISSION_ERROR,
0654: new String[] { ChatFunctions.CHAT_FUNCTION_DELETE_PREFIX });
0655: return "";
0656: }
0657: }
0658:
0659: /**
0660: * Deletes the specified message
0661: * @param message
0662: * @return String goes to the delete message page
0663: */
0664: protected String processActionDeleteMessageConfirm(
0665: DecoratedChatMessage message) {
0666: setCurrentMessage(message);
0667: //getChatManager().deleteMessage(message);
0668: return PAGE_DELETE_MESSAGE_CONFIRM;
0669: }
0670:
0671: /**
0672: * Cancels the delete of the current message
0673: * @return String goes to the room's main page
0674: */
0675: public String processActionDeleteMessageCancel() {
0676: setCurrentMessage(null);
0677: return PAGE_ENTER_ROOM;
0678: }
0679:
0680: //********************************************************************
0681: // Getters and Setters
0682:
0683: /**
0684: * This allows us to change/give the courier address.
0685: * We want the courier to respond to the chat room.
0686: * @return String
0687: */
0688: public String getCourierString() {
0689: return "/courier/" + getCurrentChatChannelId() + "/"
0690: + getToolString();
0691: }
0692:
0693: public boolean getCanManageTool() {
0694: return getMaintainer();
0695: }
0696:
0697: /**
0698: * gets the channel id of the current channel. If there isn't one then
0699: * give a blank string
0700: * @return ChatManager
0701: */
0702: public String getCurrentChatChannelId() {
0703: if (currentChannel == null)
0704: return "";
0705: return currentChannel.getChatChannel().getId();
0706: }
0707:
0708: /**
0709: * gets the current channel
0710: * @return ChatChannel
0711: */
0712: public DecoratedChatChannel getCurrentChannel() {
0713: return currentChannel;
0714: }
0715:
0716: /**
0717: * Implements a change of the chat room. It removes presence from the prior room,
0718: * adds observation of the new room, and then becomes present in the new room
0719: * @param channel
0720: */
0721: public void setCurrentChannel(DecoratedChatChannel channel) {
0722: if (presenceChannelObserver != null) {
0723: presenceChannelObserver.endObservation();
0724: presenceChannelObserver.removePresence();
0725: getChatManager().removeRoomListener(this ,
0726: channel.getChatChannel().getId());
0727: }
0728: presenceChannelObserver = null;
0729:
0730: this .currentChannel = channel;
0731:
0732: if (channel != null) {
0733: // place a presence observer on this tool.
0734: presenceChannelObserver = new PresenceObserverHelper(this ,
0735: channel.getChatChannel().getId());
0736:
0737: getChatManager().addRoomListener(this ,
0738: channel.getChatChannel().getId());
0739:
0740: presenceChannelObserver.updatePresence();
0741: }
0742: }
0743:
0744: protected void resetCurrentChannel(DecoratedChatChannel oldChannel) {
0745: if (presenceChannelObserver != null) {
0746: presenceChannelObserver.endObservation();
0747: presenceChannelObserver.removePresence();
0748: getChatManager().removeRoomListener(this ,
0749: oldChannel.getChatChannel().getId());
0750: }
0751: presenceChannelObserver = null;
0752:
0753: this .currentChannel = null;
0754: }
0755:
0756: /**
0757: * @return the currentChannelEdit
0758: */
0759: public DecoratedChatChannel getCurrentChannelEdit() {
0760: return currentChannelEdit;
0761: }
0762:
0763: /**
0764: * @param currentChannelEdit the currentChannelEdit to set
0765: */
0766: public void setCurrentChannelEdit(
0767: DecoratedChatChannel currentChannelEdit) {
0768: this .currentChannelEdit = currentChannelEdit;
0769: }
0770:
0771: /**
0772: * @return the currentMessage
0773: */
0774: public DecoratedChatMessage getCurrentMessage() {
0775: return currentMessage;
0776: }
0777:
0778: /**
0779: * @param currentMessage the currentMessage to set
0780: */
0781: public void setCurrentMessage(DecoratedChatMessage currentMessage) {
0782: this .currentMessage = currentMessage;
0783: }
0784:
0785: public DecoratedSynopticOptions lookupSynopticOptions() {
0786: DecoratedSynopticOptions dso = new DecoratedSynopticOptions();
0787: Placement placement = getToolManager().getCurrentPlacement();
0788: try {
0789: dso.setDays(Integer.parseInt(placement.getPlacementConfig()
0790: .getProperty(PARAM_DAYS)));
0791: } catch (NumberFormatException e) {
0792: dso.setDays(DEFAULT_DAYS);
0793: logger
0794: .debug("Can't get tool property for synoptic chat. Using default option");
0795: }
0796: try {
0797: dso.setItems(Integer.parseInt(placement
0798: .getPlacementConfig().getProperty(PARAM_ITEMS)));
0799: } catch (NumberFormatException e) {
0800: dso.setItems(DEFAULT_ITEMS);
0801: logger
0802: .debug("Can't get tool property for synoptic chat. Using default option");
0803: }
0804: try {
0805: dso.setChars(Integer.parseInt(placement
0806: .getPlacementConfig().getProperty(PARAM_LENGTH)));
0807: } catch (NumberFormatException e) {
0808: dso.setChars(DEFAULT_LENGTH);
0809: logger
0810: .debug("Can't get tool property for synoptic chat. Using default option");
0811: }
0812: return dso;
0813: }
0814:
0815: /**
0816: * @return the synopticOptions
0817: */
0818: public DecoratedSynopticOptions getCurrentSynopticOptions() {
0819: return currentSynopticOptions;
0820: }
0821:
0822: /**
0823: * @param synopticOptions the synopticOptions to set
0824: */
0825: public void setCurrentSynopticOptions(
0826: DecoratedSynopticOptions currentSynopticOptions) {
0827: this .currentSynopticOptions = currentSynopticOptions;
0828: }
0829:
0830: /**
0831: * This creates select items out of the channels available to the tool
0832: * @return List of SelectItem
0833: */
0834: public List getChatRoomsSelectItems() {
0835: List<SelectItem> items = new ArrayList<SelectItem>();
0836:
0837: for (Iterator i = getSiteChannels().iterator(); i.hasNext();) {
0838: ChatChannel channel = (ChatChannel) i.next();
0839: items
0840: .add(createSelect(channel.getId(), channel
0841: .getTitle()));
0842: }
0843:
0844: return items;
0845: }
0846:
0847: /**
0848: * gets the tool decorated channels
0849: * @return
0850: */
0851: public List getChatChannels() {
0852: List<DecoratedChatChannel> items = new ArrayList<DecoratedChatChannel>();
0853:
0854: for (Iterator i = getSiteChannels().iterator(); i.hasNext();) {
0855: ChatChannel channel = (ChatChannel) i.next();
0856: items.add(new DecoratedChatChannel(this , channel));
0857: }
0858:
0859: return items;
0860: }
0861:
0862: /**
0863: * gets the chatManager
0864: * @return ChatManager
0865: */
0866: public ChatManager getChatManager() {
0867: return chatManager;
0868: }
0869:
0870: public String getViewOptions() {
0871: return Integer.toString(viewOptions);
0872: }
0873:
0874: public void setViewOptions(String d) {
0875: viewOptions = Integer.parseInt(d);
0876: }
0877:
0878: protected int initMessageOptions() {
0879:
0880: int result = MESSAGEOPTIONS_ALL_MESSAGES;
0881: if (getCurrentChannel().getChatChannel().getFilterType()
0882: .equals(ChatChannel.FILTER_ALL)) {
0883: result = MESSAGEOPTIONS_ALL_MESSAGES;
0884: } else if (getCurrentChannel().getChatChannel().getFilterType()
0885: .equals(ChatChannel.FILTER_BY_NUMBER)) {
0886: result = MESSAGEOPTIONS_MESSAGES_BY_NUMBER;
0887: } else if (getCurrentChannel().getChatChannel().getFilterType()
0888: .equals(ChatChannel.FILTER_BY_TIME)) {
0889: result = MESSAGEOPTIONS_MESSAGES_BY_DATE;
0890: }
0891: return result;
0892: }
0893:
0894: /**
0895: * @return the messageOptions
0896: */
0897: public String getMessageOptions() {
0898: if (messageOptions == MESSAGEOPTIONS_NULL)
0899: messageOptions = initMessageOptions();
0900: return Integer.toString(messageOptions);
0901: }
0902:
0903: /**
0904: * @param messageOptions the messageOptions to set
0905: */
0906: public void setMessageOptions(String messageOptions) {
0907: this .messageOptions = Integer.parseInt(messageOptions);
0908: }
0909:
0910: public String getNewMessageText() {
0911: return newMessageText;
0912: }
0913:
0914: public void setNewMessageText(String newMessageText) {
0915: this .newMessageText = newMessageText;
0916: }
0917:
0918: /**
0919: * Sets the chatManager
0920: * @param chatManager ChatManager
0921: */
0922: public void setChatManager(ChatManager chatManager) {
0923: this .chatManager = chatManager;
0924: }
0925:
0926: public ToolManager getToolManager() {
0927: return toolManager;
0928: }
0929:
0930: public void setToolManager(ToolManager toolManager) {
0931: this .toolManager = toolManager;
0932: }
0933:
0934: public ColorMapper getColorMapper() {
0935: return colorMapper;
0936: }
0937:
0938: public void setColorMapper(ColorMapper colorMapper) {
0939: this .colorMapper = colorMapper;
0940: }
0941:
0942: public boolean getDisplayDate() {
0943: //2
0944: int val = Integer.parseInt(getViewOptions());
0945: return ((val & 2) == 2);
0946: //return true;
0947: }
0948:
0949: public boolean getDisplayTime() {
0950: //1
0951: int val = Integer.parseInt(getViewOptions());
0952: return ((val & 1) == 1);
0953: //return true;
0954: }
0955:
0956: public boolean getCanRenderAllMessages() {
0957: return getCanRenderMessageOptions()
0958: || getCurrentChannel().getChatChannel().getFilterType()
0959: .equals(ChatChannel.FILTER_ALL);
0960: }
0961:
0962: public boolean getCanRenderDateMessages() {
0963: return !getCanRenderMessageOptions()
0964: && getCurrentChannel().getChatChannel().getFilterType()
0965: .equals(ChatChannel.FILTER_BY_TIME);
0966: }
0967:
0968: public boolean getCanRenderNumberMessages() {
0969: return !getCanRenderMessageOptions()
0970: && getCurrentChannel().getChatChannel().getFilterType()
0971: .equals(ChatChannel.FILTER_BY_NUMBER);
0972: }
0973:
0974: public List getMessageOptionsList() {
0975: List<SelectItem> messageOptions = new ArrayList<SelectItem>();
0976: String filterType = getCurrentChannel().getChatChannel()
0977: .getFilterType();
0978: int filterParam = getCurrentChannel().getChatChannel()
0979: .getFilterParam();
0980: SelectItem item = new SelectItem(
0981: getCustomOptionValue(filterType), getCustomOptionText(
0982: filterType, filterParam));
0983: messageOptions.add(item);
0984:
0985: return messageOptions;
0986: }
0987:
0988: /**
0989: * Determins if the message option display dropdown gets rendered or not
0990: * @return
0991: */
0992: public boolean getCanRenderMessageOptions() {
0993: return getCurrentChannel().getChatChannel()
0994: .isEnableUserOverride();
0995: }
0996:
0997: protected String getCustomOptionValue(String filterType) {
0998: int val = MESSAGEOPTIONS_MESSAGES_BY_DATE;
0999: //String filterType = getCurrentChannel().getChatChannel().getFilterType();
1000: if (filterType.equals(ChatChannel.FILTER_BY_TIME)) {
1001: val = MESSAGEOPTIONS_MESSAGES_BY_DATE;
1002: } else if (filterType.equals(ChatChannel.FILTER_BY_NUMBER)) {
1003: val = MESSAGEOPTIONS_MESSAGES_BY_NUMBER;
1004: }
1005: //val = getCurrentChannel().getChatChannel().getFilterParam();
1006: return Integer.toString(val);
1007: }
1008:
1009: protected String getCustomOptionText(String filterType,
1010: int filterParam) {
1011: //int x = 3;
1012: String result = getPastXDaysText(filterParam);
1013:
1014: //x= getCurrentChannel().getChatChannel().getFilterParam();
1015: //String filterType = getCurrentChannel().getChatChannel().getFilterType();
1016: if (filterType.equals(ChatChannel.FILTER_BY_TIME)) {
1017: result = getPastXDaysText(filterParam);
1018: } else if (filterType.equals(ChatChannel.FILTER_BY_NUMBER)) {
1019: result = getPastXMessagesText(filterParam);
1020: }
1021: return result;
1022: }
1023:
1024: public boolean getSoundAlert() {
1025: return true;
1026: }
1027:
1028: public List getRoomMessages() {
1029: Date xDaysOld = null;
1030: int maxMessages = 0;
1031: int x = getCurrentChannel().getChatChannel().getFilterParam();
1032: if (Integer.parseInt(getMessageOptions()) == MESSAGEOPTIONS_MESSAGES_BY_DATE) {
1033: xDaysOld = getChatManager().calculateDateByOffset(x);
1034: maxMessages = ChatChannel.MAX_MESSAGES;
1035: } else if (Integer.parseInt(getMessageOptions()) == MESSAGEOPTIONS_MESSAGES_BY_NUMBER) {
1036: maxMessages = x;
1037: } else if (Integer.parseInt(getMessageOptions()) == MESSAGEOPTIONS_ALL_MESSAGES) {
1038: maxMessages = ChatChannel.MAX_MESSAGES;
1039: }
1040: return getMessages(getContext(), xDaysOld, maxMessages, true);
1041: }
1042:
1043: public List getSynopticMessages() {
1044: DecoratedSynopticOptions dso = lookupSynopticOptions();
1045: Date date = getChatManager().calculateDateByOffset(
1046: dso.getDays());
1047: return getMessages(getContext(), date, dso.getItems(), false);
1048: }
1049:
1050: /**
1051: *
1052: * @param context
1053: * @param limitDate
1054: * @param numMessages
1055: * @param sortAsc
1056: * @return
1057: */
1058: protected List getMessages(String context, Date limitDate,
1059: int numMessages, boolean sortAsc) {
1060: List messages = new ArrayList();
1061: try {
1062: ChatChannel channel = (currentChannel == null) ? null
1063: : currentChannel.getChatChannel();
1064: messages = getChatManager().getChannelMessages(channel,
1065: context, limitDate, numMessages, sortAsc);
1066: } catch (PermissionException e) {
1067: setErrorMessage(PERMISSION_ERROR,
1068: new String[] { ChatFunctions.CHAT_FUNCTION_READ });
1069: }
1070:
1071: List<DecoratedChatMessage> decoratedMessages = new ArrayList<DecoratedChatMessage>();
1072:
1073: for (Iterator i = messages.iterator(); i.hasNext();) {
1074: ChatMessage message = (ChatMessage) i.next();
1075:
1076: DecoratedChatMessage decoratedMessage = new DecoratedChatMessage(
1077: this , message);
1078:
1079: decoratedMessages.add(decoratedMessage);
1080: }
1081: return decoratedMessages;
1082: }
1083:
1084: public boolean getCanRemoveMessage(ChatMessage message) {
1085: return getChatManager().getCanDelete(message);
1086: }
1087:
1088: public boolean getCanRemoveChannel(ChatChannel channel) {
1089: return getChatManager().getCanDelete(channel);
1090: }
1091:
1092: public boolean getCanEditChannel(ChatChannel channel) {
1093: return getChatManager().getCanEdit(channel);
1094: }
1095:
1096: public boolean getCanCreateChannel() {
1097: return getChatManager().getCanCreateChannel();
1098: }
1099:
1100: public boolean getCanRead(ChatChannel channel) {
1101: return getChatManager().getCanReadMessage(channel);
1102: }
1103:
1104: public boolean getMaintainer() {
1105: return getChatManager().isMaintainer();
1106: }
1107:
1108: public String getMessageOwnerDisplayName(ChatMessage message) {
1109: User sender = null;
1110: try {
1111: sender = UserDirectoryService.getUser(message.getOwner());
1112: } catch (UserNotDefinedException e) {
1113: logger.error(e);
1114: return message.getOwner();
1115: }
1116: return sender.getDisplayName();
1117: }
1118:
1119: protected String getPastXDaysText(int x) {
1120: return getMessageFromBundle("past_x_days", new Object[] { x });
1121: }
1122:
1123: protected String getPastXMessagesText(int x) {
1124: return getMessageFromBundle("past_x_messages",
1125: new Object[] { x });
1126: }
1127:
1128: public String getViewingChatRoomText() {
1129: return getMessageFromBundle("viewingChatRoomText",
1130: new Object[] { getCurrentChannel().getChatChannel()
1131: .getTitle() });
1132: }
1133:
1134: private void setErrorMessage(String errorMsg, Object[] extras) {
1135: logger.debug("setErrorMessage(String " + errorMsg + ")");
1136: FacesContext.getCurrentInstance()
1137: .addMessage(
1138: null,
1139: new FacesMessage(getMessageFromBundle(errorMsg,
1140: extras)));
1141: }
1142:
1143: public String getServerUrl() {
1144: return ServerConfigurationService.getServerUrl();
1145: }
1146:
1147: //********************************************************************
1148: // Utilities
1149:
1150: /**
1151: * Gets the id of the tool we are in
1152: * @return String
1153: */
1154: public String getToolString() {
1155: return placementId;
1156: }
1157:
1158: /**
1159: * Gets the id of the site we are in
1160: * @return String
1161: */
1162: protected String getContext() {
1163: return getToolManager().getCurrentPlacement().getContext();
1164: }
1165:
1166: /**
1167: * Returns the frame identifier for resizing
1168: * @return
1169: */
1170: public String getFramePlacementId() {
1171: return Validator.escapeJavascript("Main"
1172: + getToolManager().getCurrentPlacement().getId());
1173: }
1174:
1175: /**
1176: * gets the channels in this site
1177: * @return List of ChatChannel
1178: */
1179: protected List getSiteChannels() {
1180: return getChatManager().getContextChannels(getContext(),
1181: getMessageFromBundle("default_new_channel_title"));
1182: }
1183:
1184: /**
1185: * gets the number of channels in this site
1186: * @return int
1187: */
1188: public int getSiteChannelCount() {
1189: return getChatManager().getContextChannels(getContext(),
1190: getMessageFromBundle("default_new_channel_title"))
1191: .size();
1192: }
1193:
1194: //********************************************************************
1195: // Common Utilities
1196:
1197: private ResourceLoader toolBundle;
1198:
1199: public SelectItem createSelect(Object id, String description) {
1200: SelectItem item = new SelectItem(id, description);
1201: return item;
1202: }
1203:
1204: public String getMessageFromBundle(String key, Object[] args) {
1205: return MessageFormat.format(getMessageFromBundle(key), args);
1206: }
1207:
1208: /*
1209: public FacesMessage getFacesMessageFromBundle(String key, Object[] args) {
1210: return new FacesMessage(getMessageFromBundle(key, args));
1211: }*/
1212:
1213: public String getMessageFromBundle(String key) {
1214: if (toolBundle == null) {
1215: String bundle = FacesContext.getCurrentInstance()
1216: .getApplication().getMessageBundle();
1217: toolBundle = new ResourceLoader(bundle);
1218: /* Locale requestLocale = FacesContext.getCurrentInstance().getExternalContext().getRequestLocale();
1219: if (requestLocale != null) {
1220: toolBundle = ResourceBundle.getBundle(
1221: bundle, requestLocale);
1222: }
1223: else {
1224: toolBundle = ResourceBundle.getBundle(bundle);
1225: }*/
1226: }
1227: return toolBundle.getString(key);
1228: }
1229:
1230: }
|