Index: lams_tool_mindmap/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_mindmap/.classpath (.../.classpath) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -14,14 +14,15 @@ - + - + + Index: lams_tool_mindmap/build.xml =================================================================== diff -u -r0b67ee804237056395e60ed4cca2948a595ddb72 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/build.xml (.../build.xml) (revision 0b67ee804237056395e60ed4cca2948a595ddb72) +++ lams_tool_mindmap/build.xml (.../build.xml) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -9,4 +9,23 @@ + + + + + ${ant.project.name}: Copying additional Java classes to WAR + + + \ No newline at end of file Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapNodeDAO.java =================================================================== diff -u -r2f725f8ef2aa09a2663b2335bf67213074426d11 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapNodeDAO.java (.../IMindmapNodeDAO.java) (revision 2f725f8ef2aa09a2663b2335bf67213074426d11) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapNodeDAO.java (.../IMindmapNodeDAO.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -56,7 +56,7 @@ public List getMindmapNodeByUniqueId(Long uniqueId, Long mindmapId); - public List getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId); + public MindmapNode getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId); public List getMindmapNodeByUniqueIdMindmapIdUserId(Long uniqueId, Long mindmapId, Long userId); Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapRequestDAO.java =================================================================== diff -u -r2f725f8ef2aa09a2663b2335bf67213074426d11 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapRequestDAO.java (.../IMindmapRequestDAO.java) (revision 2f725f8ef2aa09a2663b2335bf67213074426d11) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/IMindmapRequestDAO.java (.../IMindmapRequestDAO.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -38,7 +38,7 @@ public void saveOrUpdate(MindmapRequest mindmapRequest); - public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long userId, Long sessionId); + public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long sessionId); public MindmapRequest getRequestByUniqueId(Long uniqueId, Long userId, Long mindmapId, Long globalId); Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapNodeDAO.java =================================================================== diff -u -r2f725f8ef2aa09a2663b2335bf67213074426d11 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapNodeDAO.java (.../MindmapNodeDAO.java) (revision 2f725f8ef2aa09a2663b2335bf67213074426d11) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapNodeDAO.java (.../MindmapNodeDAO.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -149,9 +149,14 @@ } @Override - public List getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId) { - return this.doFind(SQL_QUERY_FIND_NODE_BY_UNIQUE_ID_SESSION_ID, + @SuppressWarnings("unchecked") + public MindmapNode getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId) { + List nodesList = (List) this.doFind(SQL_QUERY_FIND_NODE_BY_UNIQUE_ID_SESSION_ID, new Object[] { uniqueId, mindmapId, sessionId }); + if ((nodesList != null) && (nodesList.size() > 0)) { + return nodesList.get(0); + } + return null; } @Override Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapRequestDAO.java =================================================================== diff -u -rc18e6afc93561dc9bc2530cc58a37b276e712db3 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapRequestDAO.java (.../MindmapRequestDAO.java) (revision c18e6afc93561dc9bc2530cc58a37b276e712db3) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/dao/hibernate/MindmapRequestDAO.java (.../MindmapRequestDAO.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -40,8 +40,8 @@ @Repository public class MindmapRequestDAO extends LAMSBaseDAO implements IMindmapRequestDAO { private static final String SQL_QUERY_FIND_REQUESTS_AFTER_GLOBAL_ID = " from " + MindmapRequest.class.getName() - + " mr where mr.globalId > ? and " - + " mr.mindmap.uid = ? and mr.user.uid <> ? and mr.user.mindmapSession.sessionId = ? order by mr.globalId "; + + " mr where mr.mindmap.uid = ? and mr.globalId > ? and mr.user.mindmapSession.sessionId = ? " + + " order by mr.globalId "; private static final String SQL_QUERY_FIND_REQUEST_BY_UNIQUE_ID = " from " + MindmapRequest.class.getName() + " mr where mr.uniqueId = ? and mr.user.uid = ? and " + " mr.mindmap.uid = ? and mr.globalId > ? "; @@ -58,10 +58,11 @@ getSession().saveOrUpdate(mindmapRequest); } + @SuppressWarnings("unchecked") @Override - public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long userId, Long sessionId) { - return this.doFind(SQL_QUERY_FIND_REQUESTS_AFTER_GLOBAL_ID, - new Object[] { globalId, mindmapId, userId, sessionId }); + public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long sessionId) { + return (List) this.doFind(SQL_QUERY_FIND_REQUESTS_AFTER_GLOBAL_ID, + new Object[] { mindmapId, globalId, sessionId }); } @Override Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/model/MindmapRequest.java =================================================================== diff -u -r2f725f8ef2aa09a2663b2335bf67213074426d11 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/model/MindmapRequest.java (.../MindmapRequest.java) (revision 2f725f8ef2aa09a2663b2335bf67213074426d11) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/model/MindmapRequest.java (.../MindmapRequest.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -173,4 +173,12 @@ public void setMindmap(Mindmap mindmap) { this.mindmap = mindmap; } + + + @Override + public String toString() { + return "MindmapRequest [uid=" + uid + ", uniqueId=" + uniqueId + ", globalId=" + globalId + ", type=" + type + + ", nodeId=" + nodeId + ", nodeChildId=" + nodeChildId + ", user=" + user + ", mindmap=" + mindmap + + "]"; + } } \ No newline at end of file Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/IMindmapService.java =================================================================== diff -u -r9cda52bbbc8ef19343bd53f563c0734560af1a3a -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/IMindmapService.java (.../IMindmapService.java) (revision 9cda52bbbc8ef19343bd53f563c0734560af1a3a) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/IMindmapService.java (.../IMindmapService.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -114,7 +114,7 @@ public List getMindmapNodeByUniqueId(Long uniqueId, Long mindmapId); - public List getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId); + public MindmapNode getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId); public List getMindmapNodeByUniqueIdMindmapIdUserId(Long uniqueId, Long mindmapId, Long userId); @@ -131,7 +131,7 @@ public Long getNodeLastUniqueIdByMindmapUidSessionId(Long mindmapUid, Long sessionId); - public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long userId, Long sessionId); + public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long sessionId); public MindmapRequest getRequestByUniqueId(Long uniqueId, Long userId, Long mindmapId, Long globalId); Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/MindmapService.java =================================================================== diff -u -r9cda52bbbc8ef19343bd53f563c0734560af1a3a -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/MindmapService.java (.../MindmapService.java) (revision 9cda52bbbc8ef19343bd53f563c0734560af1a3a) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/service/MindmapService.java (.../MindmapService.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -899,8 +899,9 @@ } @Override - public List getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId) { + public MindmapNode getMindmapNodeByUniqueIdSessionId(Long uniqueId, Long mindmapId, Long sessionId) { return mindmapNodeDAO.getMindmapNodeByUniqueIdSessionId(uniqueId, mindmapId, sessionId); + } @Override @@ -937,8 +938,8 @@ } @Override - public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long userId, Long sessionId) { - return mindmapRequestDAO.getLastRequestsAfterGlobalId(globalId, mindmapId, userId, sessionId); + public List getLastRequestsAfterGlobalId(Long globalId, Long mindmapId, Long sessionId) { + return mindmapRequestDAO.getLastRequestsAfterGlobalId(globalId, mindmapId, sessionId); } @Override Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningAction.java =================================================================== diff -u -rfbba41ca7139d9e3cfb25defb4daa15dabe93f2e -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningAction.java (.../LearningAction.java) (revision fbba41ca7139d9e3cfb25defb4daa15dabe93f2e) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningAction.java (.../LearningAction.java) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -38,7 +38,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONArray; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; @@ -50,7 +49,6 @@ import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.tool.mindmap.dto.IdeaJSON; import org.lamsfoundation.lams.tool.mindmap.dto.MindmapDTO; -import org.lamsfoundation.lams.tool.mindmap.dto.NotifyActionJSON; import org.lamsfoundation.lams.tool.mindmap.dto.NotifyResponseJSON; import org.lamsfoundation.lams.tool.mindmap.dto.RootJSON; import org.lamsfoundation.lams.tool.mindmap.model.Mindmap; @@ -64,8 +62,6 @@ import org.lamsfoundation.lams.tool.mindmap.util.MindmapException; import org.lamsfoundation.lams.tool.mindmap.util.xmlmodel.NodeConceptModel; import org.lamsfoundation.lams.tool.mindmap.util.xmlmodel.NodeModel; -import org.lamsfoundation.lams.tool.mindmap.util.xmlmodel.NotifyRequestModel; -import org.lamsfoundation.lams.tool.mindmap.util.xmlmodel.NotifyResponseModel; import org.lamsfoundation.lams.tool.mindmap.web.forms.LearningForm; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; import org.lamsfoundation.lams.util.Configuration; @@ -96,10 +92,7 @@ private static final String REQUEST_JSON_REQUEST_ID = "requestId"; // Expected to be long private static final String REQUEST_JSON_PARENT_NODE_ID = "parentId"; // Expected to be long - private static final String RESPONSE_JSON_ACTIONS = "actions"; - - /** * Default action on page load. Clones Mindmap Nodes for each Learner in single-user mode. Uses shared (runtime * created in CopyToolContent method) Mindmap Nodes in multi-user mode. @@ -111,6 +104,7 @@ * @return null */ @Override + @SuppressWarnings("rawtypes") public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { @@ -272,6 +266,7 @@ * @param toContent * @param user */ + @SuppressWarnings("rawtypes") public void cloneMindmapNodesForRuntime(MindmapNode fromMindmapNode, MindmapNode toMindmapNode, Mindmap fromContent, Mindmap toContent, MindmapUser user, MindmapSession session) { toMindmapNode = mindmapService.saveMindmapNode(null, toMindmapNode, fromMindmapNode.getUniqueId(), @@ -296,144 +291,9 @@ * @param request * @param response * @return null - */ - public ActionForward notifyServerAction(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { - - Long userId = WebUtil.readLongParam(request, "userId", false); - Long mindmapId = WebUtil.readLongParam(request, "mindmapId", false); - Long toolSessionId = WebUtil.readLongParam(request, "sessionId", false); - String requestAction = WebUtil.readStrParam(request, "actionXML", false); - - MindmapSession mindmapSession = mindmapService.getSessionBySessionId(toolSessionId); - - NotifyRequestModel notifyRequestModel = (NotifyRequestModel) mindmapService.getXStream().fromXML(requestAction); - int requestType = notifyRequestModel.getType(); - - // if request was previously created - Long lastActionId = WebUtil.readLongParam(request, "lastActionId", false); - - MindmapRequest mindmapRequest = mindmapService.getRequestByUniqueId(notifyRequestModel.getID(), userId, - mindmapId, lastActionId); - - String notifyResponse = null; - - // if request wasn't created before, create it - if (mindmapRequest == null) { - // getting node to which changes will be applied - MindmapNode mindmapNode = null; - List mindmapNodeList = mindmapService.getMindmapNodeByUniqueIdSessionId(notifyRequestModel.getNodeID(), - mindmapId, toolSessionId); - if ((mindmapNodeList != null) && (mindmapNodeList.size() > 0)) { - mindmapNode = (MindmapNode) mindmapNodeList.get(0); - } else { - LearningAction.log.error("notifyServerAction(): Error finding node!"); - return null; - } - - // delete node - if (requestType == 0) { - // if node is created not by author or by other user... cannot delete - if (mindmapNode.getUser() == mindmapService.getUserByUID(userId)) { - - List nodes = mindmapService.getMindmapNodeByUniqueIdSessionId(notifyRequestModel.getNodeID(), - mindmapId, toolSessionId); - - //if (nodes != null && nodes.size() > 0) // check if node exists - //{ - MindmapNode curNode = (MindmapNode) nodes.get(0); - List childNodes = mindmapService.getMindmapNodeByParentIdMindmapIdSessionId(curNode.getNodeId(), - mindmapId, toolSessionId); - - if ((childNodes == null) || (childNodes.size() == 0)) // check if node has any children - { - mindmapService.deleteNodeByUniqueMindmapUser(notifyRequestModel.getNodeID(), mindmapId, userId, - toolSessionId); - mindmapRequest = saveMindmapRequest(mindmapRequest, requestType, notifyRequestModel, userId, - mindmapId, null, toolSessionId); - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), null); - } else { - notifyResponse = generateNotifyResponse(0, null, null); - } - //} else - // notifyResponse = generateNotifyResponse(0, null, null); - } else { - notifyResponse = generateNotifyResponse(0, null, null); - } - } - // create node - else if (requestType == 1) { - // no checking... users can create nodes everywhere - NodeConceptModel nodeConceptModel = notifyRequestModel.getConcept(); - - Long uniqueId = // node unique ID - mindmapService.getNodeLastUniqueIdByMindmapUidSessionId(mindmapId, toolSessionId) + 1; - - mindmapService.saveMindmapNode(null, mindmapNode, uniqueId, nodeConceptModel.getText(), - nodeConceptModel.getColor(), mindmapService.getUserByUID(userId), - mindmapService.getMindmapByUid(mindmapId), mindmapSession); - - mindmapRequest = saveMindmapRequest(mindmapRequest, requestType, notifyRequestModel, userId, mindmapId, - uniqueId, toolSessionId); - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), uniqueId); - } - // change color - else if (requestType == 2) { - if (mindmapNode.getUser() == mindmapService.getUserByUID(userId)) { - mindmapNode.setColor(notifyRequestModel.getColor()); - mindmapNode.setUser(mindmapService.getUserByUID(userId)); - mindmapService.saveOrUpdateMindmapNode(mindmapNode); - mindmapRequest = saveMindmapRequest(mindmapRequest, requestType, notifyRequestModel, userId, - mindmapId, null, toolSessionId); - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), null); - } else { - notifyResponse = generateNotifyResponse(0, null, null); - } - } - // change text - else if (requestType == 3) { - if (mindmapNode.getUser() == mindmapService.getUserByUID(userId)) { - mindmapNode.setText(notifyRequestModel.getText()); - mindmapNode.setUser(mindmapService.getUserByUID(userId)); - mindmapService.saveOrUpdateMindmapNode(mindmapNode); - mindmapRequest = saveMindmapRequest(mindmapRequest, requestType, notifyRequestModel, userId, - mindmapId, null, toolSessionId); - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), null); - } else { - notifyResponse = generateNotifyResponse(0, null, null); - } - } - } else { - if (requestType == 1) { - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), - mindmapRequest.getNodeChildId()); - } else { - notifyResponse = generateNotifyResponse(1, mindmapRequest.getGlobalId(), null); - } - } - - try { - response.setContentType("text/xml"); - response.setCharacterEncoding("utf-8"); - response.getWriter().write(notifyResponse); - } catch (IOException e) { - e.printStackTrace(); - } - - return null; - } - - - /** - * Gets the Notify Requests (Actions) from Flash and returns proper Notify Responses - * - * @param mapping - * @param form - * @param request - * @param response - * @return null * @throws JSONException */ + @SuppressWarnings("rawtypes") public ActionForward notifyServerActionJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws JSONException { @@ -464,14 +324,13 @@ else if (mindmapRequest == null) { // getting node to which changes will be applied MindmapNode mindmapNode = null; - if ( notifyRequest.has(IdeaJSON.MAPJS_JSON_ID_KEY) && requestType != 1 ) { - List mindmapNodeList = mindmapService.getMindmapNodeByUniqueIdSessionId(notifyRequest.getLong(IdeaJSON.MAPJS_JSON_ID_KEY), mindmapId, toolSessionId); - if ((mindmapNodeList != null) && (mindmapNodeList.size() > 0)) { - mindmapNode = (MindmapNode) mindmapNodeList.get(0); - } else { - LearningAction.log.error("notifyServerAction(): Error finding node!"); - return null; - } + if (notifyRequest.has(IdeaJSON.MAPJS_JSON_ID_KEY) && requestType != 1) { + mindmapNode = mindmapService.getMindmapNodeByUniqueIdSessionId( + notifyRequest.getLong(IdeaJSON.MAPJS_JSON_ID_KEY), mindmapId, toolSessionId); + if (mindmapNode == null) { + LearningAction.log.error("notifyServerAction(): Error finding node!"); + return null; + } } // delete node @@ -507,12 +366,12 @@ uniqueId = childIdFromRequest; Long parentNodeId = notifyRequest.getLong(REQUEST_JSON_PARENT_NODE_ID); - List parentNodes = mindmapService.getMindmapNodeByUniqueIdSessionId(parentNodeId, mindmapId, toolSessionId); - if (parentNodes == null || parentNodes.size() == 0 ) { + MindmapNode parentNode = mindmapService.getMindmapNodeByUniqueIdSessionId(parentNodeId, mindmapId, toolSessionId); + if (parentNode == null) { LearningAction.log.error("notifyServerAction(): Unable to find parent node: "+parentNodeId+" toolSessionId "+toolSessionId); } - MindmapNode newMindmapNode = mindmapService.saveMindmapNode(null, (MindmapNode) parentNodes.get(0), uniqueId, + mindmapService.saveMindmapNode(null, parentNode, uniqueId, notifyRequest.optString(IdeaJSON.MAPJS_JSON_TITLE_KEY), notifyRequest.optString(IdeaJSON.MAPJS_JSON_BACKGROUND_COLOR_KEY), mindmapService.getUserByUID(userId), mindmapService.getMindmapByUid(mindmapId), mindmapSession); @@ -576,31 +435,6 @@ * @param mindmapId * @param nodeChildId */ - private MindmapRequest saveMindmapRequest(MindmapRequest mindmapRequest, int requestType, - NotifyRequestModel notifyRequestModel, Long userId, Long mindmapId, Long nodeChildId, Long sessionId) { - mindmapRequest = new MindmapRequest(); - mindmapRequest.setType(requestType); - mindmapRequest.setUniqueId(notifyRequestModel.getID()); - // incrementing lastRequestId - mindmapRequest.setGlobalId(mindmapService.getLastGlobalIdByMindmapId(mindmapId, sessionId) + 1); - mindmapRequest.setUser(mindmapService.getUserByUID(userId)); - mindmapRequest.setMindmap(mindmapService.getMindmapByUid(mindmapId)); - mindmapRequest.setNodeId(notifyRequestModel.getNodeID()); - mindmapRequest.setNodeChildId(nodeChildId); // nodeChildId - mindmapService.saveOrUpdateMindmapRequest(mindmapRequest); - return mindmapRequest; - } - - /** - * Saves Notify Requests to database - * - * @param mindmapRequest - * @param requestType - * @param notifyRequestModel - * @param userId - * @param mindmapId - * @param nodeChildId - */ private MindmapRequest saveMindmapRequestJSON(MindmapRequest mindmapRequest, int requestType, Long requestId, Long nodeId, Long userId, Long mindmapId, Long nodeChildId, Long sessionId) { mindmapRequest = new MindmapRequest(); @@ -617,118 +451,6 @@ } /** - * Generated Notify Responses - * - * @param ok - * @param id - * @param data - */ - private String generateNotifyResponse(int ok, Long id, Long data) { - NotifyResponseModel nodeResponseModel = new NotifyResponseModel(); - nodeResponseModel.setOk(ok); - nodeResponseModel.setId(id); - if (data != null) { - nodeResponseModel.setData(data); - } - - return mindmapService.getXStream().toXML(nodeResponseModel); - } - - /** - * Returns lists of Poll Requests (Actions) on Mindmap Nodes made by other learners - * - * @param mapping - * @param form - * @param request - * @param response - * @return null - * @throws JSONException - */ - public ActionForward pollServerActionJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException { - - Long mindmapId = WebUtil.readLongParam(request, "mindmapId", false); - Long userId = WebUtil.readLongParam(request, "userId", false); - Long toolSessionId = WebUtil.readLongParam(request, "sessionId", false); - Long lastActionId = WebUtil.readLongParam(request, "lastActionID", false); - - JSONObject pollResponseModel = new JSONObject(); - JSONArray actions = new JSONArray(); - pollResponseModel.put(RESPONSE_JSON_ACTIONS, actions); - - List requestsList = mindmapService.getLastRequestsAfterGlobalId(lastActionId, mindmapId, userId, toolSessionId); - for (Iterator iterator = requestsList.iterator(); iterator.hasNext();) { - MindmapRequest mindmapRequest = (MindmapRequest) iterator.next(); - int requestType = mindmapRequest.getType(); - - JSONObject notifyRequestModel = null; - MindmapNode rootMindmapNode = null; - if ((requestType != 0) && (requestType != 1)) { - List nodesList = mindmapService.getMindmapNodeByUniqueIdSessionId(mindmapRequest.getNodeId(), mindmapId, - toolSessionId); - - if ((nodesList != null) && (nodesList.size() > 0)) { - rootMindmapNode = (MindmapNode) nodesList.get(0); - } else { - LearningAction.log.error("pollServerAction(): Error finding node while changing text or color!"); - } - } - - MindmapNode mindmapNode = null; - if (requestType == 1) { - List nodesList = mindmapService.getMindmapNodeByUniqueIdSessionId(mindmapRequest.getNodeChildId(), - mindmapId, toolSessionId); - - if ((nodesList != null) && (nodesList.size() > 0)) { - mindmapNode = (MindmapNode) nodesList.get(0); - } else { - LearningAction.log.error("pollServerAction(): Error finding node while creating a node!"); - } - } - - // delete node - if (requestType == 0) { - notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), - mindmapRequest.getType(), null, null, null, null); - } - // create node - else if (requestType == 1) { - String creator = null; - MindmapUser mindmapUser = mindmapNode.getUser(); - if (mindmapUser != null) { - creator = mindmapUser.getFirstName() + " " + mindmapUser.getLastName(); - } else { - creator = "Student"; - } - notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), - mindmapRequest.getType(), mindmapRequest.getNodeChildId(), mindmapNode.getText(), - mindmapNode.getColor(), creator); - } - // change color - else if (requestType == 2) { - notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), - mindmapRequest.getType(), null, null, rootMindmapNode.getColor(), null); - } - // change text - else if (requestType == 3) { - notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), - mindmapRequest.getType(), null, rootMindmapNode.getText(), null, null); - } - - actions.put(notifyRequestModel); - } - - try { - response.setContentType("application/x-json;charset=utf-8"); - response.getWriter().write(pollResponseModel.toString()); - } catch (IOException e) { - e.printStackTrace(); - } - - return null; - } - - /** * Returns the serialized JSON of the Mindmap Nodes from Database * * @param mapping @@ -739,6 +461,7 @@ * @throws JSONException * @throws IOException */ + @SuppressWarnings("rawtypes") public ActionForward setMindmapContentJSON(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws JSONException, IOException { Index: lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningWebsocketServer.java =================================================================== diff -u --- lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningWebsocketServer.java (revision 0) +++ lams_tool_mindmap/src/java/org/lamsfoundation/lams/tool/mindmap/web/actions/LearningWebsocketServer.java (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -0,0 +1,290 @@ +package org.lamsfoundation.lams.tool.mindmap.web.actions; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.websocket.CloseReason; +import javax.websocket.CloseReason.CloseCodes; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.json.JSONArray; +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.tool.mindmap.dto.NotifyActionJSON; +import org.lamsfoundation.lams.tool.mindmap.model.MindmapNode; +import org.lamsfoundation.lams.tool.mindmap.model.MindmapRequest; +import org.lamsfoundation.lams.tool.mindmap.model.MindmapSession; +import org.lamsfoundation.lams.tool.mindmap.model.MindmapUser; +import org.lamsfoundation.lams.tool.mindmap.service.IMindmapService; +import org.lamsfoundation.lams.tool.mindmap.service.MindmapServiceProxy; +import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** + * Sends Node changes to Learners. + * @author Fiona Malikoff, based on code from Marcin Cieslak + */ +@ServerEndpoint("/learningWebsocket") +public class LearningWebsocketServer { + + /** + * A singleton which updates Learners with node changes. + */ + private static class SendWorker extends Thread { + private boolean stopFlag = false; + // how ofter the thread runs + private static final long CHECK_INTERVAL = 3000; + + @Override + public void run() { + while (!stopFlag) { + try { + // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually + HibernateSessionManager.openSession(); + Iterator>> entryIterator = LearningWebsocketServer.websockets.entrySet() + .iterator(); + // go through activities and update registered learners with reports and vote count + while (entryIterator.hasNext()) { + Entry> entry = entryIterator.next(); + Long toolSessionId = entry.getKey(); + // if all learners left the activity, remove the obsolete mapping + Set sessionWebsockets = entry.getValue(); + if (sessionWebsockets.isEmpty()) { + entryIterator.remove(); + LearningWebsocketServer.globalIdCache.remove(toolSessionId); + continue; + } + SendWorker.send(toolSessionId, null, null); + } + } catch (Exception e) { + // error caught, but carry on + LearningWebsocketServer.log.error("Error in Mindmap worker thread", e); + } finally { + HibernateSessionManager.closeSession(); + try { + Thread.sleep(SendWorker.CHECK_INTERVAL); + } catch (InterruptedException e) { + LearningWebsocketServer.log.warn("Stopping Mindmap worker thread"); + stopFlag = true; + } + } + } + } + + /** + * Feeds websockets with reports and votes. + */ + private static void send(Long toolSessionId, Session newWebsocket, Long userLastGlobalId) throws JSONException, IOException { + Long previousGlobalId = LearningWebsocketServer.globalIdCache.get(toolSessionId); + if (previousGlobalId == null) { + // first time run, create the cache + previousGlobalId = 0L; + LearningWebsocketServer.globalIdCache.put(toolSessionId, previousGlobalId); + } + + MindmapSession mindmapSession = LearningWebsocketServer.getMindmapService() + .getSessionBySessionId(toolSessionId); + + JSONObject responseJSON = null; + // new user joined. Send everything from their initial globalId sent when the websocket was created + if (newWebsocket != null) { + responseJSON = getServerActionJSON(mindmapSession.getMindmap().getUid(), + mindmapSession.getSessionId(), userLastGlobalId); + newWebsocket.getBasicRemote().sendText(responseJSON.toString()); + + // send all requests since previousGlobalId + } else { + Long currentMaxGlobalId = getMindmapService().getLastGlobalIdByMindmapId( + mindmapSession.getMindmap().getUid(), mindmapSession.getSessionId()); + if (currentMaxGlobalId > previousGlobalId) { + responseJSON = getServerActionJSON(mindmapSession.getMindmap().getUid(), + mindmapSession.getSessionId(), previousGlobalId); + LearningWebsocketServer.globalIdCache.put(toolSessionId, currentMaxGlobalId); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + for (Session websocket : sessionWebsockets) { + websocket.getBasicRemote().sendText(responseJSON.toString()); + } + } + } + } + + private static final String RESPONSE_JSON_ACTIONS = "actions"; + + private static JSONObject getServerActionJSON(Long mindmapId, Long toolSessionId, Long lastActionId) + throws JSONException { + + JSONObject sendJSONObject = new JSONObject(); + JSONArray actions = new JSONArray(); + sendJSONObject.put(RESPONSE_JSON_ACTIONS, actions); + + List requestsList = mindmapService.getLastRequestsAfterGlobalId(lastActionId, mindmapId, toolSessionId); + for (Iterator iterator = requestsList.iterator(); iterator.hasNext();) { + MindmapRequest mindmapRequest = iterator.next(); + int requestType = mindmapRequest.getType(); + + JSONObject notifyRequestModel = null; + MindmapNode mindmapNode = null; + MindmapNode childMindmapNode = null; + if ((requestType != 0)) { + + mindmapNode = mindmapService.getMindmapNodeByUniqueIdSessionId(mindmapRequest.getNodeId(), + mindmapId, toolSessionId); + if (mindmapNode == null) { + LearningWebsocketServer.log.error( + "getServerActionJSON(): Error finding node while sending data about adding child, changing text or color. Cannot send request to clients. Request details:" + + mindmapRequest); + continue; + } + + if (requestType == 1) { + childMindmapNode = mindmapService.getMindmapNodeByUniqueIdSessionId( + mindmapRequest.getNodeChildId(), mindmapId, toolSessionId); + if (childMindmapNode == null) { + LearningWebsocketServer.log.error( + "pollServerAction(): Error finding node while sending data about creating a child node. Cannot send request to clients. Cannot send request to clients. Request details:" + + mindmapRequest); + continue; + } + } + } + + // delete node + if (requestType == 0) { + notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), + mindmapRequest.getType(), null, null, null, null); + } + // create node + else if (requestType == 1) { + String creator = null; + MindmapUser mindmapUser = childMindmapNode.getUser(); + if (mindmapUser != null) { + creator = mindmapUser.getFirstName() + " " + mindmapUser.getLastName(); + } else { + creator = "Student"; + } + notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), + mindmapRequest.getType(), mindmapRequest.getNodeChildId(), childMindmapNode.getText(), + childMindmapNode.getColor(), creator); + } + // change color + else if (requestType == 2) { + notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), + mindmapRequest.getType(), null, null, mindmapNode.getColor(), null); + } + // change text + else if (requestType == 3) { + notifyRequestModel = new NotifyActionJSON(mindmapRequest.getGlobalId(), mindmapRequest.getNodeId(), + mindmapRequest.getType(), null, mindmapNode.getText(), null, null); + } + + actions.put(notifyRequestModel); + } + + return sendJSONObject; + } + } + + + private static Logger log = Logger.getLogger(LearningWebsocketServer.class); + + private static IMindmapService mindmapService; + + private static final SendWorker sendWorker = new SendWorker(); + // maps toolSessionId -> cached session data + private static final Map globalIdCache = new ConcurrentHashMap<>(); + private static final Map> websockets = new ConcurrentHashMap<>(); + + static { + // run the singleton thread + LearningWebsocketServer.sendWorker.start(); + } + + /** + * Registeres the Learner for processing by SendWorker. + */ + @OnOpen + public void registerUser(Session websocket) throws JSONException, IOException { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + Long lastActionId = Long.valueOf(websocket.getRequestParameterMap().get("lastActionId").get(0)); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + if (sessionWebsockets == null) { + sessionWebsockets = ConcurrentHashMap.newKeySet(); + LearningWebsocketServer.websockets.put(toolSessionId, sessionWebsockets); + } + sessionWebsockets.add(websocket); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + + " entered Mindmap with toolSessionId: " + toolSessionId + " lastActionId: "+lastActionId); + } + + new Thread(() -> { + try { + HibernateSessionManager.openSession(); + SendWorker.send(toolSessionId, websocket, lastActionId); + } catch (Exception e) { + log.error("Error while sending messages", e); + } finally { + HibernateSessionManager.closeSession(); + } + }).start(); + } + + /** + * When user leaves the activity. + */ + @OnClose + public void unregisterUser(Session websocket, CloseReason reason) { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + LearningWebsocketServer.websockets.get(toolSessionId).remove(websocket); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + // If there was something wrong with the connection, put it into logs. + LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + + " left Mindmap with Tool Session ID: " + toolSessionId + + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) + || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) + ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + + reason.getReasonPhrase() + : "")); + } + } + + /** + * Receives a message sent by Learner via a websocket. + */ + @OnMessage + public void receiveRequest(String input, Session websocket) throws JSONException { + if (StringUtils.isBlank(input)) { + return; + } + if (input.equalsIgnoreCase("ping")) { + // just a ping every few minutes + return; + } + log.warn("Unexpected request received by Mindmap websocket. Message is being ignored. Message was: " + input); + } + + private static IMindmapService getMindmapService() { + if (LearningWebsocketServer.mindmapService == null) { + LearningWebsocketServer.mindmapService = MindmapServiceProxy + .getMindmapService(SessionManager.getServletContext()); + } + return LearningWebsocketServer.mindmapService; + } + +} \ No newline at end of file Index: lams_tool_mindmap/web/common/mapjs.jsp =================================================================== diff -u -rc4111cb04c54f01b5ba38e9f193e00039cfd7e18 -r0e594c4a472245d5f4fc8b4978d20a1e7c99867b --- lams_tool_mindmap/web/common/mapjs.jsp (.../mapjs.jsp) (revision c4111cb04c54f01b5ba38e9f193e00039cfd7e18) +++ lams_tool_mindmap/web/common/mapjs.jsp (.../mapjs.jsp) (revision 0e594c4a472245d5f4fc8b4978d20a1e7c99867b) @@ -10,8 +10,8 @@