Index: lams_tool_chat/db/sql/create_lams_tool_chat.sql =================================================================== diff -u -rf6a03ee21a18654d54498cd94d9f68fbea3b996a -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/db/sql/create_lams_tool_chat.sql (.../create_lams_tool_chat.sql) (revision f6a03ee21a18654d54498cd94d9f68fbea3b996a) +++ lams_tool_chat/db/sql/create_lams_tool_chat.sql (.../create_lams_tool_chat.sql) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -12,8 +12,8 @@ create table tl_lachat11_attachment (uid bigint not null auto_increment, file_version_id bigint, file_type varchar(255), file_name varchar(255), file_uuid bigint, create_date datetime, chat_uid bigint, primary key (uid))ENGINE=InnoDB; create table tl_lachat11_chat (uid bigint not null auto_increment, create_date datetime, update_date datetime, create_by bigint, title varchar(255), instructions text, run_offline bit, lock_on_finished bit, reflect_on_activity bit, reflect_instructions text, online_instructions text, offline_instructions text, content_in_use bit, define_later bit, tool_content_id bigint, filtering_enabled bit, filter_keywords text, submission_deadline datetime default null, primary key (uid))ENGINE=InnoDB; create table tl_lachat11_message (uid bigint not null auto_increment, chat_session_uid bigint not null, from_user_uid bigint, to_user_uid bigint, type varchar(255), body text, send_date datetime, hidden bit, primary key (uid))ENGINE=InnoDB; -create table tl_lachat11_session (uid bigint not null auto_increment, session_end_date datetime, session_start_date datetime, status integer, session_id bigint, session_name varchar(250), chat_uid bigint, jabber_room varchar(250), room_created bit, primary key (uid))ENGINE=InnoDB; -create table tl_lachat11_user (uid bigint not null auto_increment, user_id bigint, last_name varchar(255), login_name varchar(255), first_name varchar(255), jabber_id varchar(255), finishedActivity bit, jabber_nickname varchar(255), chat_session_uid bigint, primary key (uid))ENGINE=InnoDB; +create table tl_lachat11_session (uid bigint not null auto_increment, session_end_date datetime, session_start_date datetime, status integer, session_id bigint, session_name varchar(250), chat_uid bigint, primary key (uid))ENGINE=InnoDB; +create table tl_lachat11_user (uid bigint not null auto_increment, user_id bigint, last_name varchar(255), login_name varchar(255), first_name varchar(255), finishedActivity bit, nickname varchar(255), chat_session_uid bigint, primary key (uid))ENGINE=InnoDB; CREATE TABLE tl_lachat11_conditions ( condition_id BIGINT(20) NOT NULL Fisheye: Tag ecb763befc0380d0810f5794203bfcdf9ca0bfe7 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/JabberHTTPBind/JHBServlet.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ecb763befc0380d0810f5794203bfcdf9ca0bfe7 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/JabberHTTPBind/Janitor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ecb763befc0380d0810f5794203bfcdf9ca0bfe7 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/JabberHTTPBind/Response.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag ecb763befc0380d0810f5794203bfcdf9ca0bfe7 refers to a dead (removed) revision in file `lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/JabberHTTPBind/Session.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatSessionDAO.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatSessionDAO.java (.../IChatSessionDAO.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatSessionDAO.java (.../IChatSessionDAO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -36,8 +36,6 @@ void saveOrUpdate(ChatSession session); ChatSession getBySessionId(Long toolSessionId); - - ChatSession getByJabberRoom(String jabberRoom); void deleteBySessionID(Long toolSessionID); } Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatUserDAO.java =================================================================== diff -u -r9e446244a7245a4e8893e4673a801c56e4a35334 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatUserDAO.java (.../IChatUserDAO.java) (revision 9e446244a7245a4e8893e4673a801c56e4a35334) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/IChatUserDAO.java (.../IChatUserDAO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -52,24 +52,16 @@ /** * - * @param jabberID - * @param jabberRoom - * @return - */ - ChatUser getByJabberIDAndJabberRoom(String jabberID, String jabberRoom); - - /** - * * @param uid * @return */ ChatUser getByUID(Long uid); /** * - * @param jabberNickname + * @param nickname * @param chatSession * @return */ - ChatUser getByJabberNicknameAndSessionID(String jabberNickname, Long sessionID); + ChatUser getByNicknameAndSessionID(String nickname, Long sessionID); } \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatSessionDAO.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatSessionDAO.java (.../ChatSessionDAO.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatSessionDAO.java (.../ChatSessionDAO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -38,9 +38,6 @@ public static final String SQL_QUERY_FIND_BY_SESSION_ID = "from " + ChatSession.class.getName() + " where session_id=?"; - public static final String SQL_QUERY_FIND_BY_JABBER_ROOM = "from " - + ChatSession.class.getName() + " where jabber_room=?"; - public void saveOrUpdate(ChatSession session) { this.getHibernateTemplate().saveOrUpdate(session); this.getHibernateTemplate().flush(); @@ -54,14 +51,6 @@ return (ChatSession) list.get(0); } - public ChatSession getByJabberRoom(String jabberRoom) { - List list = this.getHibernateTemplate().find( - SQL_QUERY_FIND_BY_JABBER_ROOM, jabberRoom); - if (list == null || list.isEmpty()) - return null; - return (ChatSession) list.get(0); - } - public void deleteBySessionID(Long toolSessionID) { ChatSession session = getBySessionId(toolSessionID); if(session != null){ Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatUserDAO.java =================================================================== diff -u -r9e446244a7245a4e8893e4673a801c56e4a35334 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatUserDAO.java (.../ChatUserDAO.java) (revision 9e446244a7245a4e8893e4673a801c56e4a35334) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dao/hibernate/ChatUserDAO.java (.../ChatUserDAO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -43,16 +43,12 @@ + ChatUser.class.getName() + " as f where login_name=? and f.chatSession.sessionId=?"; - public static final String SQL_QUERY_FIND_BY_JABBER_ID_JABBER_ROOM = "from " - + ChatUser.class.getName() - + " as f where jabber_id=? and f.chatSession.jabberRoom=?"; - private static final String SQL_QUERY_FIND_BY_UID = "from " + ChatUser.class.getName() + " where uid=?"; private static final String SQL_QUERY_FIND_BY_NICKNAME_AND_SESSION = "from " + ChatUser.class.getName() - + " as f where jabber_nickname=? and f.chatSession.sessionId=?"; + + " as f where nickname=? and f.chatSession.sessionId=?"; public ChatUser getByUserIdAndSessionId(Long userId, Long toolSessionId) { List list = this.getHibernateTemplate().find( @@ -79,19 +75,6 @@ } - public ChatUser getByJabberIDAndJabberRoom(String jabberID, - String jabberRoom) { - - List list = this.getHibernateTemplate().find( - SQL_QUERY_FIND_BY_JABBER_ID_JABBER_ROOM, - new Object[] { jabberID, jabberRoom }); - - if (list == null || list.isEmpty()) - return null; - - return (ChatUser) list.get(0); - } - public void saveOrUpdate(ChatUser chatUser) { this.getHibernateTemplate().saveOrUpdate(chatUser); this.getHibernateTemplate().flush(); @@ -107,9 +90,9 @@ return (ChatUser) list.get(0); } - public ChatUser getByJabberNicknameAndSessionID(String jabberNickname, Long sessionID) { + public ChatUser getByNicknameAndSessionID(String nickname, Long sessionID) { List list = this.getHibernateTemplate().find(SQL_QUERY_FIND_BY_NICKNAME_AND_SESSION, - new Object[] { jabberNickname, sessionID }); + new Object[] { nickname, sessionID }); if (list == null || list.isEmpty()) return null; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20121024.sql =================================================================== diff -u --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20121024.sql (revision 0) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dbupdates/patch20121024.sql (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -0,0 +1,16 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; + +----------------------Put all sql statements below here------------------------- + +ALTER TABLE tl_lachat11_user DROP COLUMN jabber_id, + CHANGE COLUMN jabber_nickname nickname varchar(255); + +ALTER TABLE tl_lachat11_session DROP COLUMN jabber_room, + DROP COLUMN room_created; + +----------------------Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatMessageDTO.java =================================================================== diff -u -rda54b82e5ef860fe9f8872b75f2b1718cfb7de32 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatMessageDTO.java (.../ChatMessageDTO.java) (revision da54b82e5ef860fe9f8872b75f2b1718cfb7de32) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatMessageDTO.java (.../ChatMessageDTO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -44,7 +44,7 @@ public Boolean hidden; public ChatMessageDTO(ChatMessage chatMessage) { - this.from = chatMessage.getFromUser().getJabberNickname(); + this.from = chatMessage.getFromUser().getNickname(); this.body = chatMessage.getBody(); this.type = chatMessage.getType(); this.sendDate = chatMessage.getSendDate(); Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatUserDTO.java =================================================================== diff -u -rda54b82e5ef860fe9f8872b75f2b1718cfb7de32 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatUserDTO.java (.../ChatUserDTO.java) (revision da54b82e5ef860fe9f8872b75f2b1718cfb7de32) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/dto/ChatUserDTO.java (.../ChatUserDTO.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -33,7 +33,7 @@ public String loginName; - public String jabberNickname; + public String nickname; public String firstName; @@ -52,7 +52,7 @@ public ChatUserDTO(ChatUser user) { this.uid = user.getUid(); this.loginName = user.getLoginName(); - this.jabberNickname = user.getJabberNickname(); + this.nickname = user.getNickname(); this.firstName = user.getFirstName(); this.lastName = user.getLastName(); this.userID = user.getUserId(); @@ -78,12 +78,12 @@ this.firstName = firstName; } - public String getJabberNickname() { - return jabberNickname; + public String getNickname() { + return nickname; } - public void setJabberNickname(String jabberNickname) { - this.jabberNickname = jabberNickname; + public void setNickname(String nickname) { + this.nickname = nickname; } public String getLastName() { Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatMessage.java =================================================================== diff -u -rda54b82e5ef860fe9f8872b75f2b1718cfb7de32 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatMessage.java (.../ChatMessage.java) (revision da54b82e5ef860fe9f8872b75f2b1718cfb7de32) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatMessage.java (.../ChatMessage.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -30,7 +30,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; /** - * Represents a jabber message sent by a user toUser a groupchat session + * Represents a message sent by a user toUser a groupchat session * * @author Anthony Sukkar * @@ -42,6 +42,10 @@ * */ private static final long serialVersionUID = -3976906267301586708L; + + public static final String MESSAGE_TYPE_PUBLIC = "groupchat"; + + public static final String MESSAGE_TYPE_PRIVATE = "chat"; // Fields private Long uid; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatSession.java =================================================================== diff -u -r3a00494e8ecd90ce49d79927d74b4a6b96ba853a -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatSession.java (.../ChatSession.java) (revision 3a00494e8ecd90ce49d79927d74b4a6b96ba853a) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatSession.java (.../ChatSession.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -61,11 +61,7 @@ private Chat chat; private Set chatUsers; - - private String jabberRoom; - - private boolean roomCreated; - + private Set chatMessages; // Constructors @@ -196,28 +192,6 @@ } /** - * @hibernate.property column="jabber_room" length="250" - */ - public String getJabberRoom() { - return jabberRoom; - } - - public void setJabberRoom(String jabberRoom) { - this.jabberRoom = jabberRoom; - } - - /** - * @hibernate.property column="room_created" - */ - public boolean isRoomCreated() { - return roomCreated; - } - - public void setRoomCreated(boolean roomCreated) { - this.roomCreated = roomCreated; - } - - /** * @hibernate.set lazy="true" inverse="true" cascade="none" * @hibernate.collection-key column="chat_session_uid" * @hibernate.collection-one-to-many class="org.lamsfoundation.lams.tool.chat.model.ChatMessage" Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatUser.java =================================================================== diff -u -rda54b82e5ef860fe9f8872b75f2b1718cfb7de32 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatUser.java (.../ChatUser.java) (revision da54b82e5ef860fe9f8872b75f2b1718cfb7de32) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/model/ChatUser.java (.../ChatUser.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -54,12 +54,10 @@ private String loginName; private ChatSession chatSession; - - private String jabberId; - + private boolean finishedActivity; - private String jabberNickname; + private String nickname; // Constructors @@ -145,17 +143,6 @@ } /** - * @hibernate.property column="jabber_id" length="255" - */ - public String getJabberId() { - return jabberId; - } - - public void setJabberId(String jabberId) { - this.jabberId = jabberId; - } - - /** * @hibernate.property column="finishedActivity" */ public boolean isFinishedActivity() { @@ -167,14 +154,14 @@ } /** - * @hibernate.property column="jabber_nickname" + * @hibernate.property column="nickname" */ - public String getJabberNickname() { - return jabberNickname; + public String getNickname() { + return nickname; } - public void setJabberNickname(String jabberNickname) { - this.jabberNickname = jabberNickname; + public void setNickname(String nickname) { + this.nickname = nickname; } /** Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/ChatService.java =================================================================== diff -u -r37b49e5e78d2b57936d98e68f6057539472b7725 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/ChatService.java (.../ChatService.java) (revision 37b49e5e78d2b57936d98e68f6057539472b7725) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/ChatService.java (.../ChatService.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -26,32 +26,21 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Hashtable; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.Random; import java.util.Set; import java.util.SortedMap; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.upload.FormFile; -import org.hibernate.Hibernate; -import org.hibernate.id.Configurable; -import org.hibernate.id.IdentifierGenerator; -import org.hibernate.id.UUIDHexGenerator; import org.lamsfoundation.lams.contentrepository.AccessDeniedException; import org.lamsfoundation.lams.contentrepository.ICredentials; import org.lamsfoundation.lams.contentrepository.ITicket; @@ -96,19 +85,13 @@ import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.tool.service.ILamsToolService; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.Configuration; -import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.WebUtil; -import org.lamsfoundation.lams.util.XMPPUtil; import org.lamsfoundation.lams.util.audit.IAuditService; import org.lamsfoundation.lams.util.wddx.WDDXProcessor; import org.lamsfoundation.lams.util.wddx.WDDXProcessorConversionException; -import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.w3c.dom.Text; /** * An implementation of the IChatService interface. @@ -148,17 +131,6 @@ private Random generator = new Random(); - // - private IdentifierGenerator idGenerator; - - public ChatService() { - super(); - - // configure the indentifier generator - idGenerator = new UUIDHexGenerator(); - ((Configurable) idGenerator).configure(Hibernate.STRING, new Properties(), null); - } - /* Methods from ToolSessionManager */ public void createToolSession(Long toolSessionId, String toolSessionName, Long toolContentId) throws ToolException { if (ChatService.logger.isDebugEnabled()) { @@ -170,13 +142,6 @@ session.setSessionId(toolSessionId); session.setSessionName(toolSessionName); - String jabberRoom = (String) idGenerator.generate(null, null) + "@" - + Configuration.get(ConfigurationKeys.XMPP_CONFERENCE); - session.setJabberRoom(jabberRoom); - - // the jabber room is created when the first learner starts - session.setRoomCreated(false); - Chat chat = chatDAO.getByContentId(toolContentId); session.setChat(chat); chatSessionDAO.saveOrUpdate(session); @@ -235,7 +200,6 @@ public void removeToolSession(Long toolSessionId) throws DataMissingException, ToolException { chatSessionDAO.deleteBySessionID(toolSessionId); // TODO check if cascade worked - // do we need to remove room on jabber server ? } /** @@ -450,14 +414,6 @@ return chatSession; } - public ChatSession getSessionByJabberRoom(String jabberRoom) { - ChatSession chatSession = chatSessionDAO.getByJabberRoom(jabberRoom); - if (chatSession == null) { - ChatService.logger.debug("Could not find the chat session with jabberRoom:" + jabberRoom); - } - return chatSession; - } - public ChatUser getUserByUserIdAndSessionId(Long userId, Long toolSessionId) { return chatUserDAO.getByUserIdAndSessionId(userId, toolSessionId); } @@ -466,16 +422,12 @@ return chatUserDAO.getByLoginNameAndSessionId(loginName, toolSessionId); } - public ChatUser getUserByJabberIDAndJabberRoom(String jabberID, String jabberRoom) { - return chatUserDAO.getByJabberIDAndJabberRoom(jabberID, jabberRoom); - } - public ChatUser getUserByUID(Long uid) { return chatUserDAO.getByUID(uid); } - public ChatUser getUserByJabberNicknameAndSessionID(String jabberNickname, Long sessionID) { - return chatUserDAO.getByJabberNicknameAndSessionID(jabberNickname, sessionID); + public ChatUser getUserByNicknameAndSessionID(String nickname, Long sessionID) { + return chatUserDAO.getByNicknameAndSessionID(nickname, sessionID); } public List getMessagesForUser(ChatUser chatUser) { @@ -539,249 +491,44 @@ public synchronized ChatUser createChatUser(UserDTO user, ChatSession chatSession) { ChatUser chatUser = new ChatUser(user, chatSession); - String jabberId = XMPPUtil.createId(user); - if (jabberId == null) { - ChatService.logger.error("Unable to create jabber id for user: " + user.getUserID()); - } - chatUser.setJabberId(jabberId); - chatUser.setJabberNickname(createJabberNickname(chatUser)); + + chatUser.setNickname(createNickname(chatUser)); saveOrUpdateChatUser(chatUser); return chatUser; } - public String createJabberNickname(ChatUser chatUser) { - String desiredJabberNickname = chatUser.getFirstName() + " " + chatUser.getLastName(); - String jabberNickname = desiredJabberNickname; + private String createNickname(ChatUser chatUser) { + String desiredNickname = chatUser.getFirstName() + " " + chatUser.getLastName(); + String nickname = desiredNickname; boolean valid = false; int count = 1; // TODO may need max tries to prevent possibly entering infinite loop. while (!valid) { - if (getUserByJabberNicknameAndSessionID(jabberNickname, chatUser.getChatSession().getSessionId()) == null) { - // jabberNickname is available + if (getUserByNicknameAndSessionID(nickname, chatUser.getChatSession().getSessionId()) == null) { + // nickname is available valid = true; } else { - jabberNickname = desiredJabberNickname + " " + count; + nickname = desiredNickname + " " + count; count++; } } - return jabberNickname; + return nickname; } - public void processIncomingMessages(NodeList messageElems) { - - for (int i = 0; i < messageElems.getLength(); i++) { - // extract message attributes - Node message = messageElems.item(i); - NamedNodeMap nnm = message.getAttributes(); - - Node from = nnm.getNamedItem("from"); - Node to = nnm.getNamedItem("to"); - Node type = nnm.getNamedItem("type"); - - Node body = getBodyElement(message); - - // save the messages. - ChatMessage chatMessage = new ChatMessage(); - String jabberRoom; - String toNick = ""; - - // setting to field - if (type.getNodeValue().equals("chat")) { - // we are sending to an individual user. - // extract the jabber room from the to field. - // format is room@domain/nick - int index = to.getNodeValue().lastIndexOf("/"); - if (index == -1) { - ChatService.logger.debug("processIncomingMessages: malformed 'to' attribute :" + to.getNodeValue()); - return; // somethings wrong, ignore packet - } - jabberRoom = to.getNodeValue().substring(0, index); - toNick = to.getNodeValue().substring(index + 1); - } else if (type.getNodeValue().equals("groupchat")) { - // we are sending to the whole room. - // format is room@domain - jabberRoom = to.getNodeValue(); - } else { - ChatService.logger.debug("processIncomingMessages: unknown type: " + type.getNodeValue()); - return; - } - - ChatSession chatSession = this.getSessionByJabberRoom(jabberRoom); - ChatUser toChatUser = getUserByJabberNicknameAndSessionID(toNick, chatSession.getSessionId()); - chatMessage.setChatSession(chatSession); - chatMessage.setToUser(toChatUser); - - // setting from field - int index = from.getNodeValue().lastIndexOf("@"); - if (index == -1) { - ChatService.logger.debug("processIncomingMessages: malformed 'from' attribute :" + from.getNodeValue()); - return; // somethings wrong, ignore packet - } - String JidUsername = from.getNodeValue().substring(0, index); - // NB: JID and userId are the same. - Long userId; - try { - userId = new Long(JidUsername); - } catch (NumberFormatException e) { - ChatService.logger.debug("processIncomingMessages: malformed JID username: " + JidUsername); - return; - } - ChatUser fromUser = getUserByUserIdAndSessionId(userId, chatSession.getSessionId()); - chatMessage.setFromUser(fromUser); - - chatMessage.setType(type.getNodeValue()); - Node bodyText = body.getFirstChild(); - String bodyTextStr = ""; - if (bodyText != null) { - bodyTextStr = bodyText.getNodeValue(); - } - chatMessage.setBody(bodyTextStr); - chatMessage.setSendDate(new Date()); - chatMessage.setHidden(Boolean.FALSE); - saveOrUpdateChatMessage(chatMessage); - } - } - - public List processIncomingPresence(Node presence) { - NamedNodeMap nnm = presence.getAttributes(); - - Node from = nnm.getNamedItem("from"); - Node to = nnm.getNamedItem("to"); - if (from == null || to == null) { - // somethings wrong, return empty list - ChatService.logger.debug("malformed presence xml: no from or to attributes present"); - return null; - } - /* - * // Note: Removed xmlns check due to problems with firefox 3 // checking presence packet for correct values - * Node xElem = presence.getFirstChild(); if (xElem == null) { logger.debug("malformed presence xml: no x - * element present"); } nnm = xElem.getAttributes(); Node xmlns = nnm.getNamedItem("xmlns"); if (xmlns == null || - * !xmlns.getNodeValue().equals( "http://jabber.org/protocol/muc")) { logger .debug("malformed presence xml: - * xmlns attribute for x element not available or incorrect"); return null; } - */ - - // get the Chat User - String jabberID = from.getNodeValue().split("/")[0]; - String jabberRoom = to.getNodeValue().split("/")[0]; - - ChatUser chatUser = getUserByJabberIDAndJabberRoom(jabberID, jabberRoom); - - List chatMessageList = getMessagesForUser(chatUser); - ChatService.logger.debug("MESSAGE COUNT" + chatMessageList.size()); - - List xmlMessageList = new ArrayList(); - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - Document document = builder.newDocument(); - for (Iterator iter = chatMessageList.iterator(); iter.hasNext();) { - ChatMessage message = (ChatMessage) iter.next(); - - Element messageElement = document.createElement("message"); - messageElement.setAttribute("from", jabberRoom + "/" + message.getFromUser().getJabberNickname()); - messageElement.setAttribute("to", jabberID + "/lams_chatclient"); - messageElement.setAttribute("type", message.getType()); - - Element bodyElement = document.createElement("body"); - Text bodyText = document.createTextNode(message.getBody()); - bodyElement.appendChild(bodyText); - - Element xElement = document.createElement("x"); - xElement.setAttribute("xmlns", "jabber:x:delay"); - xElement.setAttribute("stamp", "TODO"); // TODO generate the - // stamp attribute - xElement.setAttribute("from", jabberRoom + "/" + message.getFromUser().getJabberNickname()); - - messageElement.appendChild(bodyElement); - messageElement.appendChild(xElement); - filterMessage(messageElement, chatUser.getChatSession().getChat()); - - xmlMessageList.add(messageElement); - // printXMLNode(messageElement, ""); - } - } catch (ParserConfigurationException e) { - e.printStackTrace(); - ChatService.logger.debug("parser configuration exception"); - return null; - } - return xmlMessageList; - } - - private void printXMLNode(Node node, String tab) { - System.out.print(tab + node.getNodeName() + ":"); - - NamedNodeMap nnm = node.getAttributes(); - for (int j = 0; j < nnm.getLength(); j++) { - Node m = nnm.item(j); - System.out.print(" " + m.getNodeName() + "=" + m.getNodeValue()); - } - System.out.print(" => " + node.getNodeValue() + "\n"); - - NodeList nl = node.getChildNodes(); - for (int i = 0; i < nl.getLength(); i++) { - Node n = nl.item(i); - printXMLNode(n, tab + " "); - } - - } - - public void filterMessage(Node message, Chat chat) { + public String filterMessage(String message, Chat chat) { Pattern pattern = getFilterPattern(chat); - if (pattern == null) { - return; - } - // get the message body node - Node body = getBodyElement(message); - if (body == null) { - // no body node present - return; - } - - // get the text node - Node bodyText = body.getFirstChild(); - if (bodyText == null) { - // no text present - return; - } - - // filter the message. - Matcher matcher = pattern.matcher(bodyText.getNodeValue()); - bodyText.setNodeValue(matcher.replaceAll(ChatConstants.FILTER_REPLACE_TEXT)); - } - - public void filterMessage(Node message) { - NamedNodeMap nnm = message.getAttributes(); - String from = nnm.getNamedItem("from").getNodeValue(); - - // extracting jabber room. - int index = from.lastIndexOf("/"); - String jabberRoom; - if (index != -1) { - jabberRoom = from.substring(0, index); - } else { - jabberRoom = from; - } - - // get the chat content3 - Chat chat = getSessionByJabberRoom(jabberRoom).getChat(); - filterMessage(message, chat); - } - - public void filterMessage(ChatMessageDTO messageDTO, Chat chat) { - Pattern pattern = getFilterPattern(chat); - if (pattern == null) { - return; + return message; } - Matcher matcher = pattern.matcher(messageDTO.getBody()); - messageDTO.setBody(matcher.replaceAll(ChatConstants.FILTER_REPLACE_TEXT)); + Matcher matcher = pattern.matcher(message); + return matcher.replaceAll(ChatConstants.FILTER_REPLACE_TEXT); } - + private Pattern getFilterPattern(Chat chat) { if (!chat.isFilteringEnabled()) { return null; @@ -857,25 +604,6 @@ /* Private methods */ private Map messageFilters = new ConcurrentHashMap(); - private Node getBodyElement(Node message) { - // get the body element - NodeList nl = message.getChildNodes(); - Node body = null; - for (int j = 0; j < nl.getLength(); j++) { - // We are looking for the element. - // More than one may exists, we will take the first one we see - // We ignore and elements - // TODO check that the first one is right. may have problems with - // multiple langauges. - Node msgChild = nl.item(j); - if (msgChild.getNodeName() == "body") { - body = msgChild; - break; - } - } - return body; - } - private NodeKey processFile(FormFile file, String type) { NodeKey node = null; if (file != null && !StringUtils.isEmpty(file.getFileName())) { Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/IChatService.java =================================================================== diff -u -r17be8146c14155314d21784f5a24b6e10ee4818a -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/IChatService.java (.../IChatService.java) (revision 17be8146c14155314d21784f5a24b6e10ee4818a) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/service/IChatService.java (.../IChatService.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -41,7 +41,6 @@ import org.lamsfoundation.lams.tool.chat.util.ChatMessageFilter; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; /** * Defines the services available to the web layer from the Chat Service @@ -108,13 +107,6 @@ public ChatSession getSessionBySessionId(Long toolSessionId); /** - * - * @param jabberRoom - * @return - */ - public ChatSession getSessionByJabberRoom(String jabberRoom); - - /** * @param chatSession */ public void saveOrUpdateChatSession(ChatSession chatSession); @@ -137,26 +129,18 @@ /** * - * @param jabberID - * @param jabberRoom - * @return - */ - public ChatUser getUserByJabberIDAndJabberRoom(String jabberID, String jabberRoom); - - /** - * * @param uid * @return */ public ChatUser getUserByUID(Long uid); /** * - * @param jabberNickname + * @param nickname * @param sessionID * @return */ - public ChatUser getUserByJabberNicknameAndSessionID(String jabberNickname, Long sessionID); + public ChatUser getUserByNicknameAndSessionID(String nickname, Long sessionID); /** * @@ -187,45 +171,15 @@ /** * - * @param messageElems - */ - public void processIncomingMessages(NodeList messageElems); - - /** - * - * @param presenceElems - */ - public List processIncomingPresence(Node presence); - - /** - * * @param toolContentID * @param pattern */ public ChatMessageFilter updateMessageFilters(Chat chat); + public String filterMessage(String message, Chat chat); + /** * - * @param node - */ - public void filterMessage(Node message); - - /** - * - * @param message - * @param chat - */ - public void filterMessage(Node message, Chat chat); - - /** - * - * @param messageDTO - * @param chat - */ - public void filterMessage(ChatMessageDTO messageDTO, Chat chat); - - /** - * * @param messageUID * @return */ Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatConstants.java =================================================================== diff -u -r9f7df51118e418eead64378c028572b0baf39196 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatConstants.java (.../ChatConstants.java) (revision 9f7df51118e418eead64378c028572b0baf39196) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatConstants.java (.../ChatConstants.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -40,6 +40,8 @@ public static final int MONITORING_SUMMARY_MAX_MESSAGES = 5; + public static final long PRESENCE_IDLE_TIMEOUT = 20 * 1000; + // Attribute names public static final String ATTR_MESSAGE = "message"; public static final String ATTR_SESSION_MAP = "sessionMap"; Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatMessageFilter.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatMessageFilter.java (.../ChatMessageFilter.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/util/ChatMessageFilter.java (.../ChatMessageFilter.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -41,7 +41,7 @@ regex = regex.replaceAll("[" + "\\(" + "\\)" + "\\[" + "\\]" + "\\{" + "\\}" + "\\\\" + "\\^" + "\\$" + "\\|" + "\\?" + "\\*" + "\\+" + "\\." + "]+", " "); - regex = regex.replaceAll("[\\s]+", " "); + regex = regex.replaceAll("[\\s,]+", " "); regex = regex.trim(); regex = regex.replaceAll(" ", "|"); Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningAction.java =================================================================== diff -u -r228482c7a091c7691a9fc9651e46a8d98e29a6e1 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningAction.java (.../LearningAction.java) (revision 228482c7a091c7691a9fc9651e46a8d98e29a6e1) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/actions/LearningAction.java (.../LearningAction.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -25,24 +25,34 @@ package org.lamsfoundation.lams.tool.chat.web.actions; import java.io.IOException; +import java.util.Collections; import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.TimeZone; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.ToolSessionManager; import org.lamsfoundation.lams.tool.chat.dto.ChatDTO; import org.lamsfoundation.lams.tool.chat.dto.ChatUserDTO; import org.lamsfoundation.lams.tool.chat.model.Chat; +import org.lamsfoundation.lams.tool.chat.model.ChatMessage; import org.lamsfoundation.lams.tool.chat.model.ChatSession; import org.lamsfoundation.lams.tool.chat.model.ChatUser; import org.lamsfoundation.lams.tool.chat.service.ChatServiceProxy; @@ -53,11 +63,8 @@ import org.lamsfoundation.lams.tool.exception.DataMissingException; import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.Configuration; -import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.DateUtil; import org.lamsfoundation.lams.util.WebUtil; -import org.lamsfoundation.lams.util.XMPPUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; @@ -78,6 +85,10 @@ private IChatService chatService; + private static final Map> presence = Collections + .synchronizedMap(new HashMap>()); + + @Override public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // 'toolSessionID' and 'mode' paramters are expected to be present. @@ -108,25 +119,9 @@ request.setAttribute("MODE", mode.toString()); - // Create the room if it doesn't exist - log.debug(chatSession.isRoomCreated()); - if (!chatSession.isRoomCreated()) { - if (XMPPUtil.createMultiUserChat(chatSession.getJabberRoom())) { - chatSession.setRoomCreated(true); - } else { - chatSession.setRoomCreated(false); - log.error("Unable to create chat room " + chatSession.getJabberRoom()); - } - - chatService.saveOrUpdateChatSession(chatSession); - } - ChatDTO chatDTO = new ChatDTO(chat); request.setAttribute("chatDTO", chatDTO); - request.setAttribute("XMPPDOMAIN", Configuration.get(ConfigurationKeys.XMPP_DOMAIN)); - request.setAttribute("CONFERENCEROOM", chatSession.getJabberRoom()); - ChatUserDTO chatUserDTO = new ChatUserDTO(chatUser); if (chatUser.isFinishedActivity()) { // get the notebook entry. @@ -150,46 +145,28 @@ } /* Check if submission deadline is null */ - + Date submissionDeadline = chatDTO.getSubmissionDeadline(); request.setAttribute("chatDTO", chatDTO); - + if (submissionDeadline != null) { - HttpSession ss = SessionManager.getSession(); - UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); - TimeZone learnerTimeZone = learnerDto.getTimeZone(); - Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); - Date currentLearnerDate = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, new Date()); - request.setAttribute("submissionDeadline", submissionDeadline); - - //calculate whether submission deadline has passed, and if so forward to "runOffline" - if (currentLearnerDate.after(tzSubmissionDeadline)) { - return mapping.findForward("runOffline"); - - } - - } + HttpSession ss = SessionManager.getSession(); + UserDTO learnerDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone learnerTimeZone = learnerDto.getTimeZone(); + Date tzSubmissionDeadline = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, submissionDeadline); + Date currentLearnerDate = DateUtil.convertToTimeZoneFromDefault(learnerTimeZone, new Date()); + request.setAttribute("submissionDeadline", submissionDeadline); + // calculate whether submission deadline has passed, and if so forward to "runOffline" + if (currentLearnerDate.after(tzSubmissionDeadline)) { + return mapping.findForward("runOffline"); - - return mapping.findForward("learning"); + } - } - - private ChatUser getCurrentUser(Long toolSessionId) { - UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); - - // attempt to retrieve user using userId and toolSessionId - ChatUser chatUser = chatService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), - toolSessionId); - - if (chatUser == null) { - ChatSession chatSession = chatService.getSessionBySessionId(toolSessionId); - chatUser = chatService.createChatUser(user, chatSession); } - return chatUser; + return mapping.findForward("learning"); } public ActionForward finishActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, @@ -203,7 +180,7 @@ chatUser.setFinishedActivity(true); chatService.saveOrUpdateChatUser(chatUser); } else { - log.error("finishActivity(): couldn't find ChatUser with uid: " + lrnForm.getChatUserUID()); + LearningAction.log.error("finishActivity(): couldn't find ChatUser with uid: " + lrnForm.getChatUserUID()); } ToolSessionManager sessionMgrService = ChatServiceProxy.getChatSessionManager(getServlet().getServletContext()); @@ -277,4 +254,133 @@ return finishActivity(mapping, form, request, response); } -} + + /** + * Get data displayed in Learner Chat screen. + */ + public ActionForward getChatContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws JSONException, IOException { + Long toolSessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + ChatUser chatUser = getCurrentUser(toolSessionID); + Long lastMessageUid = WebUtil.readLongParam(request, "lastMessageUid", true); + + // build JSON object for Javascript to understand + JSONObject responseJSON = new JSONObject(); + getMessages(lastMessageUid, chatUser, responseJSON); + getRoster(chatUser, responseJSON); + + response.getWriter().write(responseJSON.toString()); + return null; + } + + /** + * Stores message sent by user. + */ + public ActionForward sendMessage(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws JSONException, IOException { + String message = request.getParameter("message"); + if (StringUtils.isBlank(message)) { + return null; + } + Long toolSessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + + ChatUser toChatUser = null; + String toUser = request.getParameter(AttributeNames.USER); + if (!StringUtils.isBlank(toUser)) { + toChatUser = chatService.getUserByNicknameAndSessionID(toUser, toolSessionID); + if (toChatUser == null) { + // there should be an user, but he could not be found, so don't send the message to everyone + LearningAction.log.error("Could not find nick: " + toUser + " in session: " + toolSessionID); + return null; + } + } + + ChatUser chatUser = getCurrentUser(toolSessionID); + + ChatMessage chatMessage = new ChatMessage(); + chatMessage.setFromUser(chatUser); + chatMessage.setChatSession(chatUser.getChatSession()); + chatMessage.setToUser(toChatUser); + chatMessage.setType(toChatUser == null ? ChatMessage.MESSAGE_TYPE_PUBLIC : ChatMessage.MESSAGE_TYPE_PRIVATE); + chatMessage.setBody(message); + chatMessage.setSendDate(new Date()); + chatMessage.setHidden(Boolean.FALSE); + chatService.saveOrUpdateChatMessage(chatMessage); + + return null; + } + + @SuppressWarnings("unchecked") + private void getMessages(Long lastMessageUid, ChatUser chatUser, JSONObject responseJSON) throws JSONException { + List messages = chatService.getMessagesForUser(chatUser); + if (!messages.isEmpty()) { + // if last message which is already displayed on Chat screen + // is the same as newest message in DB, there is nothing new for user, so don't send him anything + ChatMessage lastMessage = messages.get(messages.size() - 1); + Long currentLastMessageUid = lastMessage.getUid(); + if ((lastMessageUid == null) || (currentLastMessageUid > lastMessageUid)) { + responseJSON.put("lastMessageUid", currentLastMessageUid); + + for (ChatMessage message : messages) { + // all messasges need to be written out, not only new ones, + // as old ones could have been edited or hidden by Monitor + if (!message.isHidden()) { + String filteredMessage = chatService.filterMessage(message.getBody(), chatUser.getChatSession() + .getChat()); + + JSONObject messageJSON = new JSONObject(); + messageJSON.put("body", filteredMessage); + messageJSON.put("from", message.getFromUser().getNickname()); + messageJSON.put("type", message.getType()); + responseJSON.append("messages", messageJSON); + } + } + } + } + } + + /** + * Gets users currently using the Chat instance. + */ + private void getRoster(ChatUser chatUser, JSONObject responseJSON) throws JSONException { + Long sessionId = chatUser.getChatSession().getSessionId(); + // this is equivalent of a chat room + Map sessionRoster = LearningAction.presence.get(sessionId); + if (sessionRoster == null) { + sessionRoster = Collections.synchronizedMap(new LinkedHashMap()); + LearningAction.presence.put(sessionId, sessionRoster); + } + + // store when the user polled messages the last time + long currentTime = System.currentTimeMillis(); + sessionRoster.put(chatUser.getNickname(), currentTime); + + synchronized (sessionRoster) { + Iterator nickIterator = sessionRoster.keySet().iterator(); + while (nickIterator.hasNext()) { + String nick = nickIterator.next(); + // if user did not poll messages for some time, he left the chat and is unavailable + if (currentTime - sessionRoster.get(nick) < ChatConstants.PRESENCE_IDLE_TIMEOUT) { + responseJSON.append("roster", nick); + } else { + nickIterator.remove(); + } + } + } + } + + private ChatUser getCurrentUser(Long toolSessionId) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + // attempt to retrieve user using userId and toolSessionId + ChatUser chatUser = chatService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionId); + + if (chatUser == null) { + ChatSession chatSession = chatService.getSessionBySessionId(toolSessionId); + chatUser = chatService.createChatUser(user, chatSession); + } + + return chatUser; + } +} \ No newline at end of file Index: lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/servlets/ExportServlet.java =================================================================== diff -u -re7046600ee8bfa53d053e0aee33a16b52ad0e8e2 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/servlets/ExportServlet.java (.../ExportServlet.java) (revision e7046600ee8bfa53d053e0aee33a16b52ad0e8e2) +++ lams_tool_chat/src/java/org/lamsfoundation/lams/tool/chat/web/servlets/ExportServlet.java (.../ExportServlet.java) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -162,10 +162,10 @@ sessionDTO.getUserDTOs().add(chatUserDTO); } - // filter messages - for (ChatMessageDTO msg : sessionDTO.getMessageDTOs()) { - chatService.filterMessage(msg, chatSession.getChat()); - } + // filter messages + for (ChatMessageDTO msg : sessionDTO.getMessageDTOs()) { + msg.setBody(chatService.filterMessage(msg.getBody(), chatSession.getChat())); + } ChatDTO chatDTO = new ChatDTO(chatSession.getChat()); chatDTO.getSessionDTOs().add(sessionDTO); Index: lams_tool_chat/web/includes/css/chat.css =================================================================== diff -u -r4859624c3a107b05f0e6f27039ed90e15fb650f6 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/includes/css/chat.css (.../chat.css) (revision 4859624c3a107b05f0e6f27039ed90e15fb650f6) +++ lams_tool_chat/web/includes/css/chat.css (.../chat.css) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -14,35 +14,39 @@ /* ==================== LEARNING PAGE STYLES ==================== */ +#chatContent { + table-layout: fixed; + margin-top: 10px; + border-spacing: 10px; +} -#iResp { +#messages { height: 260px; - width: 75%; overflow: auto; border: 1px solid #999; padding: 2px; padding-left:5px; } #roster { - width: 20%; height: 260px; overflow: auto; border: 1px solid #999; font-weight: bold; padding: 2px; - float: right; } + +#sendMessageArea { + border: 1px solid #999; + width: 99%; +} -#send-button { - float: right; - width: 105px; - overflow: auto; +#sendMessageButtonCell { + text-align: right; } - -#send-message-area { - margin-right: 12px; - overflow: auto; + +#sendMessageButton { + width: 100%; } .selected { @@ -57,13 +61,6 @@ cursor: pointer; } -#msgArea { - width: 95%; - margin:0; - margin-right:20px; - border: 1px solid #999; -} - /* ================== MONITORING ================== */ .edit-pane { display: none;; Index: lams_tool_chat/web/includes/css/chat_rtl.css =================================================================== diff -u -r60d54756f59597b6c1df8e0f9103a39898391b5e -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/includes/css/chat_rtl.css (.../chat_rtl.css) (revision 60d54756f59597b6c1df8e0f9103a39898391b5e) +++ lams_tool_chat/web/includes/css/chat_rtl.css (.../chat_rtl.css) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -14,37 +14,41 @@ /* ==================== LEARNING PAGE STYLES ==================== */ +#chatContent { + table-layout: fixed; + margin-top: 10px; + border-spacing: 10px; +} -#iResp { +#messages { height: 260px; - width: 75%; overflow: auto; border: 1px solid #999; padding: 2px; padding-right:5px; } #roster { - width: 20%; height: 260px; overflow: auto; border: 1px solid #999; font-weight: bold; padding: 2px; - float: left; } -#send-button { - float: left; - width: 105px; - overflow: auto; +#sendMessageArea { + border: 1px solid #999; + width: 99%; } - -#send-message-area { - margin-left: 12px; - overflow: auto; + +#sendMessageButtonCell { + text-align: right; } +#sendMessageButton { + width: 100%; +} + .selected { background-color: #ececec; padding: 2px; @@ -57,13 +61,6 @@ cursor: pointer; } -#msgArea { - width: 95%; - margin:0; - margin-left:20px; - border: 1px solid #999; -} - /* ================== MONITORING ================== */ .edit-pane { display: none;; Index: lams_tool_chat/web/includes/javascript/learning.js =================================================================== diff -u -ra3fa9d47a50a02348e23d312f82f181151573a5c -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/includes/javascript/learning.js (.../learning.js) (revision a3fa9d47a50a02348e23d312f82f181151573a5c) +++ lams_tool_chat/web/includes/javascript/learning.js (.../learning.js) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -1,330 +1,115 @@ - -/* ******* Constants ******* */ -var GROUPCHAT_MSG = ""; -var PRIVATE_MSG = "private_message"; +// for chat users to be indetified by different colours var PALETTE = ["#0000FF", "#006699", "#0066FF", "#6633FF", "#00CCFF", "#009900", "#00CC33", "#339900", "#008080", "#66FF66", "#CC6600", "#FF6600", "#FF9900", "#CC6633", "#FF9933", "#990000", "#A50021", "#990033", "#CC3300", "#FF6666", "#330033", "#663399", "#6633CC", "#660099", "#FF00FF", "#999900", "#808000", "#FF9FF2", "#666633", "#292929", "#666666"]; -/* ******* Helper Functions ******* */ -function getColour(nick) { - var charSum = 0; - for (var i = 0; i < nick.length; i++) { - charSum += nick.charCodeAt(i); +// only Monitor can send a personal message +var selectedUser = null; +// last message in chat window +var lastMessageUid = null; +var pollInProgress = false; + +function updateChat() { + if (!pollInProgress) { + // synchronise: if polling takes too long, don't try to do it again + pollInProgress = true; + $.ajax({ + url : LEARNING_ACTION, + data : {'dispatch' : 'getChatContent', + 'toolSessionID' : TOOL_SESSION_ID, + 'lastMessageUid' : lastMessageUid + }, + cache : false, + dataType : 'json', + success : handleUpdateChatResult, + complete : function(){ + pollInProgress = false; + } + }); } - return PALETTE[charSum % (PALETTE.length)]; } -function htmlEnc(str) { - if (!str) { - return null; - } - str = str.replace(/&/g, "&"); - str = str.replace(//g, ">"); - str = str.replace(/\"/g, """); - str = str.replace(/\n/g, "
"); - return str; -} -function createElem(name, attrs, style, text) { - var e = document.createElement(name); - if (attrs) { - for (var key in attrs) { - if (key == "attrClass") { - e.className = attrs[key]; - } else { - if (key == "attrId") { - e.id = attrs[key]; - } else { - e.setAttribute(key, attrs[key]); - } - } - } - } - if (style) { - for (key in style) { - e.style[key] = style[key]; - } - } - if (text) { - e.appendChild(document.createTextNode(text)); - } - return e; -} -/* ******* Roster ******* */ -function RosterUser(nick) { - this.nick = nick; - this.status = "unavailable"; -} -function getRosterUserByNick(nick) { - for (var i = 0; i < this.users.length; i++) { - if (this.users[i].nick == nick) { - return this.users[i]; - } - } - return null; -} -function AddRosterUser(user) { - this.users[this.users.length] = user; -} -function UpdateRosterUser(user) { - // TODO do we need this. -} -function RemoveRosterUser() { -} -function UpdateRosterDisplay() { - var rosterDiv = document.getElementById("roster"); - rosterDiv.innerHTML = ""; - for (var i = 0; i < this.users.length; i++) { - if (this.users[i].status != "unavailable") { - var className = "unselected"; - if (i == this.currentIndex) { - className = "selected"; - } - var nick = this.users[i].nick; - var userDiv = createElem("div", {attrId:"user-" + i, attrClass:className, onClick:"selectUser(this);"}, {width:"100%", color:getColour(this.users[i].nick)}, this.users[i].nick); - rosterDiv.appendChild(userDiv); - } - } + +function handleUpdateChatResult(result) { + if (result.lastMessageUid) { + messageDiv.html(''); + // all messasges need to be written out, not only new ones, + // as old ones could have been edited or hidden by Monitor + + jQuery.each(result.messages, function(){ + var container = $('
',{ + 'class' : 'message ' + (this.type == 'chat' ? 'private_message' : '') + }).css('color' , getColour(this.from)); + $('
',{ + 'class' : 'messageFrom', + 'text' : this.from + }).appendTo(container); + $('',{ + 'text' : this.body + }).appendTo(container); + + container.appendTo(messageDiv); + }); + + lastMessageUid = result.lastMessageUid; + messageDiv.scrollTop(messageDiv.prop('scrollHeight')); + } + + rosterDiv.html(''); + jQuery.each(result.roster, function(){ + var userDiv = $('
', { + 'class' : (this == selectedUser ? 'selected' : 'unselected'), + 'text' : this + }).css('color', getColour(this)) + .appendTo(rosterDiv); - // IE hack to ensure onclick event work when rosterDiv is updated. Only being used when in teacher mode. - if (navigator.appName == "Microsoft Internet Explorer" && MODE == "teacher") { - rosterDiv.parentNode.innerHTML = rosterDiv.parentNode.innerHTML; - // following commands are ignored by IE unless we use a delay - var t1 = setTimeout("scrollMessageDisplay()", 5); - var t2 = setTimeout("setFocusOnTextarea()", 5); + // only Monitor can send a personal message + if (MODE == 'teacher') { + userDiv.click(function(){ + userSelected($(this)); + }); } + }); } -function Roster() { - this.users = []; - this.currentIndex = null; - // objects methods - this.getUserByNick = getRosterUserByNick; - this.addUser = AddRosterUser; - this.updateUser = UpdateRosterUser; - this.removeUser = RemoveRosterUser; - this.updateDisplay = UpdateRosterDisplay; -} -var roster = new Roster(); -function selectUser(userDiv) { - if (MODE == "teacher") { - var newIndex = userDiv.id.substring(userDiv.id.indexOf("-") + 1, userDiv.id.length); - if (roster.currentIndex == newIndex) { - roster.currentIndex = null; - } else { - roster.currentIndex = newIndex; - } - - // update "send message to" display - var sendToUserSpan = document.getElementById("sendToUser"); - var sendToEveryoneSpan = document.getElementById("sendToEveryone"); - if (roster.currentIndex == null) { - sendToEveryoneSpan.style.display = "inline"; - sendToUserSpan.style.display = "none"; - } else { - sendToEveryoneSpan.style.display = "none"; - sendToUserSpan.style.display = "inline"; - var nick = roster.users[roster.currentIndex].nick; - var nickElem = createElem("span", null, {color:getColour(nick)}, nick); - sendToUserSpan.innerHTML = ""; // clear previous user name - sendToUserSpan.appendChild(nickElem); - } - roster.updateDisplay(); + +function userSelected(userDiv) { + var userDivContent = userDiv.html(); + // is Monitor clicked the already selectedd user, desect him and make message go to everyone + selectedUser = userDivContent == selectedUser ? null : userDivContent; + + if (selectedUser) { + sendToUserSpan.html(selectedUser) + .css('color', getColour(selectedUser)); } + sendToEveryoneSpan.css('display', selectedUser ? 'none' : 'inline'); + sendToUserSpan.css('display', selectedUser ? 'inline' : 'none'); + $('.selected').attr('class', 'unselected'); + userDiv.attr('class', selectedUser ? 'selected' : 'unselected'); } -/* ******* Chat functions ******* */ -function setFocusOnTextarea() { - document.forms[0].msg.focus(); -} -function scrollMessageDisplay() { - var iRespDiv = document.getElementById("iResp"); - iRespDiv.scrollTop = iRespDiv.scrollHeight; -} -function generateMessageHTML(nick, message, type) { - var colour = getColour(nick); - var fromElem = createElem("div", {attrClass:"messageFrom"}, null, nick); - var msgElem = createElem("div", {attrClass:"message " + type}, {color:colour}, null); - msgElem.innerHTML = message; - msgElem.insertBefore(fromElem, msgElem.firstChild); - return msgElem; -} -function updateMessageDisplay(htmlMessage) { - var iRespDiv = document.getElementById("iResp"); - iRespDiv.appendChild(htmlMessage); - iRespDiv.scrollTop = iRespDiv.scrollHeight; -} -function sendMsg(aForm) { - if (aForm.msg.value === "") { + +function sendMessage() { + var message = sendMessageArea.val(); + if (!message || message == '') { return false; // do not send empty messages. } - var aMsg = new JSJaCMessage(); - if (MODE == "teacher" && !(roster.currentIndex === null)) { - var toNick = roster.users[roster.currentIndex].nick; - aMsg.setTo(CONFERENCEROOM + "/" + toNick); - aMsg.setType("chat"); - var message = "[" + toNick + "] " + aForm.msg.value; - aMsg.setBody(message); - // apending the private message to the incoming window, - // since the jabber server will not echo sent private messages. - // TODO: need to check if this is correct behaviour - if (!(NICK == toNick)) { - updateMessageDisplay(generateMessageHTML(NICK, message, PRIVATE_MSG)); - } - } else { - aMsg.setTo(CONFERENCEROOM); - aMsg.setType("groupchat"); - aMsg.setBody(aForm.msg.value); - } - - // } - aMsg.setFrom(USERNAME + "@" + XMPPDOMAIN + "/" + RESOURCE); - con.send(aMsg); - aForm.msg.value = ""; - return false; -} -/* ******* Event Handlers ******* */ -function handleEvent(aJSJaCPacket) { - document.getElementById("iResp").innerHTML += "IN (raw):
" + htmlEnc(aJSJaCPacket.xml()) + "
"; -} -function handleMessage(aJSJaCPacket) { - var nick = aJSJaCPacket.getFrom().substring(aJSJaCPacket.getFrom().indexOf("/") + 1); - var message = htmlEnc(aJSJaCPacket.getBody()); - var type = aJSJaCPacket.getType(); - var htmlMessage; - if (type == "chat") { - htmlMessage = generateMessageHTML(nick, message, PRIVATE_MSG); - } else { - if (type == "groupchat") { - htmlMessage = generateMessageHTML(nick, message, GROUPCHAT_MSG); - } else { - /* somethings wrong, dont add anything.*/ - htmlMessage = ""; - } - } - updateMessageDisplay(htmlMessage); -} -function handlePresence(presence) { - var from = presence.getFrom(); - var status = presence.getStatus(); - var show = presence.getShow(); - var type = presence.getType(); - // get x element for MUC - var x; - for (var i = 0; i < presence.getNode().getElementsByTagName("x").length; i++) { - if (presence.getNode().getElementsByTagName("x").item(i).getAttribute("xmlns") == "http://jabber.org/protocol/muc#user") { - x = presence.getNode().getElementsByTagName("x").item(i); - break; - } - } + sendMessageArea.val(''); - // extract nick. - var nick; - if (from.indexOf("/") != -1) { - nick = from.substring(from.indexOf("/") + 1); - } - var user = roster.getUserByNick(nick); - if (!user) { - user = new RosterUser(nick); - roster.addUser(user); - } - if (show) { - user.status = show; - } else { - if (type) { - if (type == "unavailable") { - user.status = "unavailable"; - } - } else { - // default: means presence is available. - user.status = "available"; - } - } - roster.updateDisplay(); -} -function handleConnected() { - if (MODE == "learner" && LEARNER_FINISHED == "true" && LOCK_ON_FINISHED == "true") { - // disable sending messages. - document.getElementById("msgArea").disabled = "disabled"; - var sendButton = document.getElementById("sendButton"); - sendButton.disabled = "disabled"; - sendButton.className = "disabled"; - } + // only Monitor can send a personal message + var isPrivate = MODE == 'teacher' && selectedUser; - // clear the response window. - document.getElementById("iResp").innerHTML = ""; - - // send presence - var aPresence = new JSJaCPresence(); - aPresence.setTo(CONFERENCEROOM + "/" + NICK); - aPresence.setFrom(USERNAME + "@" + XMPPDOMAIN); - var x = aPresence.getDoc().createElement("x"); - x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); - x.appendChild(aPresence.getDoc().createElement("password")).appendChild(aPresence.getDoc().createTextNode(PASSWORD)); - aPresence.getNode().appendChild(x); - con.send(aPresence); - - // set up roster - roster = new Roster(); + $.ajax({ + url : LEARNING_ACTION, + data : {'dispatch' : 'sendMessage', + 'toolSessionID' : TOOL_SESSION_ID, + 'message' : isPrivate ? '[' + selectedUser + '] ' + message : message, + 'user' : isPrivate ? selectedUser : null + }, + cache : false, + success : updateChat + }); } -function handleError(e) { - document.getElementById("msgArea").disabled = "disabled"; - document.getElementById("sendButton").disabled = "disabled"; - document.getElementById("sendButton").className = "disabled"; - document.getElementById("iResp").innerHTML = "Couldn't connect. Please try again...
" + htmlEnc("Code: " + e.getAttribute("code") + "\nType: " + e.getAttribute("type") + "\nCondition: " + e.firstChild.nodeName); - document.getElementById("roster").innerHTML = ""; -} -/* ******* Init ******* */ -function doLogin() { - try { - // setup args for contructor - var oArgs = {httpbase:HTTPBASE, timerval:6000}; - if (typeof (oDbg) != "undefined") { - oArgs.oDbg = oDbg; - } - con = new JSJaCHttpBindingConnection(oArgs); - con.registerHandler("message", handleMessage); - con.registerHandler("presence", handlePresence); - con.registerHandler("iq", handleEvent); - con.registerHandler("onconnect", handleConnected); - con.registerHandler("onerror", handleError); - - // setup args for connect method - oArgs = {domain:XMPPDOMAIN, username:USERNAME, resource:RESOURCE, pass:PASSWORD}; - con.connect(oArgs); +function getColour(nick) { + // same nick should give same colour + var charSum = 0; + for ( var i = 0; i < nick.length; i++) { + charSum += nick.charCodeAt(i); } - catch (e) { - document.getElementById("iResp").innerHTML = e.toString(); - } - finally { - return false; - } -} -function init() { - if (typeof (Debugger) == "function") { - var oDbg = new Debugger(4, "simpleclient"); - oDbg.start(); - } - doLogin(); -} -onload = init; -onunload = function () { - if (typeof (con) != "undefined" && con.disconnect) { - con.disconnect(); - } -}; -/* ******* Helper functions ******* */ -function checkEnter(e) { //e is event object passed from function invocation - var characterCode; //literal character code will be stored in this variable - if (e && e.which) { //if which property of event object is supported (NN4) - e = e; - characterCode = e.which; //character code is contained in NN4's which property - } else { - e = event; - characterCode = e.keyCode; //character code is contained in IE's keyCode property - } - if (characterCode == 13) { //if generated character code is equal to ascii 13 (if enter key) - //document.forms[0].submit(); //submit the form - sendMsg(document.forms[0]); - return false; - } else { - return true; - } -} - + return PALETTE[charSum % (PALETTE.length)]; +} \ No newline at end of file Index: lams_tool_chat/web/pages/learning/learning.jsp =================================================================== diff -u -r9f7df51118e418eead64378c028572b0baf39196 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/pages/learning/learning.jsp (.../learning.jsp) (revision 9f7df51118e418eead64378c028572b0baf39196) +++ lams_tool_chat/web/pages/learning/learning.jsp (.../learning.jsp) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -1,34 +1,34 @@ <%@ include file="/common/taglibs.jsp"%> - - - - - - - - - + + - - -

@@ -59,54 +59,38 @@

-   - -
-
-
- - -
-
- message.loading -
- -
- - + + + + + + + + + + - - + + + + + + + + +
- label.sendMessageTo - label.everyone - + + +
- - -
- - - - - - - - -
- - - - -
- -
- - - - - <%@ include file="parts/finishButton.jsp"%> +
+
+ + <%@ include file="parts/finishButton.jsp"%> + +
\ No newline at end of file Index: lams_tool_chat/web/pages/monitoring/statistics.jsp =================================================================== diff -u -r0321578dd45b96f11b886ddbca8999538073c6cc -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/pages/monitoring/statistics.jsp (.../statistics.jsp) (revision 0321578dd45b96f11b886ddbca8999538073c6cc) +++ lams_tool_chat/web/pages/monitoring/statistics.jsp (.../statistics.jsp) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -40,7 +40,7 @@ - ${user.jabberNickname} + ${user.nickname} ${user.postCount} Index: lams_tool_chat/web/pages/monitoring/summary.jsp =================================================================== diff -u -r35a0e719d061c08b52e705135bb2f2126079ed21 -recb763befc0380d0810f5794203bfcdf9ca0bfe7 --- lams_tool_chat/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision 35a0e719d061c08b52e705135bb2f2126079ed21) +++ lams_tool_chat/web/pages/monitoring/summary.jsp (.../summary.jsp) (revision ecb763befc0380d0810f5794203bfcdf9ca0bfe7) @@ -209,7 +209,7 @@ - ${user.jabberNickname} + ${user.nickname} ${user.postCount}