Index: lams_tool_scribe/.classpath =================================================================== diff -u -r0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/.classpath (.../.classpath) (revision 0fdf00ad8ffebc0cc6d79de96a216c08ce0d4cdf) +++ lams_tool_scribe/.classpath (.../.classpath) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -20,6 +20,7 @@ + Index: lams_tool_scribe/build.xml =================================================================== diff -u -re59bc835a5ec91886980d67af70c0f05a0f7ae73 -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/build.xml (.../build.xml) (revision e59bc835a5ec91886980d67af70c0f05a0f7ae73) +++ lams_tool_scribe/build.xml (.../build.xml) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -3,5 +3,23 @@ - + + + + + + ${ant.project.name}: Copying additional Java classes to WAR + + \ No newline at end of file Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/scribeApplicationContext.xml =================================================================== diff -u -ra6641bf9262a01d07740a517643f8fe187ec5b1f -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/scribeApplicationContext.xml (.../scribeApplicationContext.xml) (revision a6641bf9262a01d07740a517643f8fe187ec5b1f) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/scribeApplicationContext.xml (.../scribeApplicationContext.xml) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -40,6 +40,7 @@ PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED + PROPAGATION_REQUIRED PROPAGATION_REQUIRED,-java.lang.Exception PROPAGATION_REQUIRED PROPAGATION_REQUIRED Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/IScribeService.java =================================================================== diff -u -rbe07c35c372d904a65581d98660e73f3b13b69db -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/IScribeService.java (.../IScribeService.java) (revision be07c35c372d904a65581d98660e73f3b13b69db) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/IScribeService.java (.../IScribeService.java) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -24,12 +24,12 @@ package org.lamsfoundation.lams.tool.scribe.service; -import org.apache.struts.upload.FormFile; +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.tool.scribe.model.Scribe; import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; -import org.lamsfoundation.lams.tool.scribe.util.ScribeException; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; /** @@ -136,5 +136,7 @@ boolean isGroupedActivity(long toolContentID); + void submitReport(Long toolSessionId, String userName, JSONObject requestJSON) throws JSONException; + public void deleteHeading(Long headingUid); } \ No newline at end of file Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/ScribeService.java =================================================================== diff -u -r8be2bc782a2c7066c8c33f5605962584df7a2f9b -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/ScribeService.java (.../ScribeService.java) (revision 8be2bc782a2c7066c8c33f5605962584df7a2f9b) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/service/ScribeService.java (.../ScribeService.java) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -483,6 +483,37 @@ return toolService.isGroupedActivity(toolContentID); } + @Override + @SuppressWarnings("unchecked") + public void submitReport(Long toolSessionId, String userName, JSONObject requestJSON) throws JSONException { + ScribeSession scribeSession = getSessionBySessionId(toolSessionId); + ScribeUser scribe = scribeSession.getAppointedScribe(); + if ((scribe == null) || !scribe.getLoginName().equals(userName)) { + return; + } + + for (ScribeUser learner : (Set) scribeSession.getScribeUsers()) { + learner.setReportApproved(false); + saveOrUpdateScribeUser(learner); + } + + JSONArray reportsJSON = requestJSON.getJSONArray("reports"); + for (int reportIndex = 0; reportIndex < reportsJSON.length(); reportIndex++) { + JSONObject reportJSON = reportsJSON.getJSONObject(reportIndex); + Long uid = reportJSON.getLong("uid"); + String text = reportJSON.getString("text"); + for (ScribeReportEntry report : (Set) scribeSession.getScribeReportEntries()) { + if (report.getUid().equals(uid)) { + report.setEntryText(text); + break; + } + } + } + + scribeSession.setReportSubmitted(true); + saveOrUpdateScribeSession(scribeSession); + } + /* ********** Used by Spring to "inject" the linked objects ************* */ public IScribeDAO getScribeDAO() { Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/util/ScribeUtils.java =================================================================== diff -u -r0edacde89fb315c54ed60643a06ef7d3e7b5bb89 -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/util/ScribeUtils.java (.../ScribeUtils.java) (revision 0edacde89fb315c54ed60643a06ef7d3e7b5bb89) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/util/ScribeUtils.java (.../ScribeUtils.java) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -1,71 +1,44 @@ package org.lamsfoundation.lams.tool.scribe.util; -import java.util.Iterator; import java.util.Set; import java.util.TreeMap; import org.lamsfoundation.lams.tool.scribe.dto.ScribeSessionDTO; import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; -import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; public class ScribeUtils { - - public static int calculateVotePercentage(int numberOfVotes, int numberOfLearners) { - - Float v = new Float(numberOfVotes); - Float l = new Float(numberOfLearners); - - Float result = v/l*100; - - return result.intValue(); - } - /** Create the session DTO for a user's session/group. Includes the number of votes - * for, percentages, etc. - * @param scribeSession - */ - public static ScribeSessionDTO createSessionDTO(ScribeSession scribeSession) { - ScribeSessionDTO sessionDTO = new ScribeSessionDTO(scribeSession); + public static int calculateVotePercentage(int numberOfVotes, int numberOfLearners) { + Float v = new Float(numberOfVotes); + Float l = new Float(numberOfLearners); - int numberOfVotes = 0; - for (Iterator iter = scribeSession.getScribeUsers().iterator(); iter - .hasNext();) { - ScribeUser user = (ScribeUser) iter.next(); - if (user.isReportApproved()) { - numberOfVotes++; - } - } + Float result = (v / l) * 100; - int numberOfLearners = scribeSession.getScribeUsers().size(); + return result.intValue(); + } - sessionDTO.setNumberOfVotes(numberOfVotes); - sessionDTO.setNumberOfLearners(numberOfLearners); - sessionDTO.setVotePercentage(ScribeUtils.calculateVotePercentage( - numberOfVotes, numberOfLearners)); + /** + * Create a map of the reports (in ScribeSessionDTO format) for all the other groups/sessions, where the key is the + * group/session name. The code ensures that the session name is unique, adding the session id if necessary. It will + * only include the finalized reports. + */ + public static TreeMap getReportDTOs(ScribeSession scribeSession) { + Set scribeSessionsForContent = scribeSession.getScribe().getScribeSessions(); + TreeMap otherScribeSessions = new TreeMap(); + for (ScribeSession session : scribeSessionsForContent) { + if (!session.equals(scribeSession) && session.isForceComplete()) { - return sessionDTO; - } - - /** Create a map of the reports (in ScribeSessionDTO format) for all the other groups/sessions, where the key - * is the group/session name. The code ensures that the session name is unique, adding the session id if necessary. - * It will only include the finalized reports. */ - public static TreeMap getReportDTOs(ScribeSession scribeSession) { - Set scribeSessionsForContent = scribeSession.getScribe().getScribeSessions(); - TreeMap otherScribeSessions = new TreeMap(); - for ( ScribeSession session : scribeSessionsForContent ) { - if ( ! session.equals(scribeSession) && session.isForceComplete() ) { - - // ensure a unique group name, as we will sort on that - String sessionKey = session.getSessionName(); - if ( otherScribeSessions.containsKey(sessionKey) ) { - sessionKey = sessionKey + "("+session.getSessionId().toString()+")"; - } - - ScribeSessionDTO dto = new ScribeSessionDTO(session); - otherScribeSessions.put(sessionKey, dto); - } + // ensure a unique group name, as we will sort on that + String sessionKey = session.getSessionName(); + if (otherScribeSessions.containsKey(sessionKey)) { + sessionKey = sessionKey + "(" + session.getSessionId().toString() + ")"; } - return otherScribeSessions; + + ScribeSessionDTO dto = new ScribeSessionDTO(session); + otherScribeSessions.put(sessionKey, dto); + } } + return otherScribeSessions; + } } Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningAction.java =================================================================== diff -u -rbe07c35c372d904a65581d98660e73f3b13b69db -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningAction.java (.../LearningAction.java) (revision be07c35c372d904a65581d98660e73f3b13b69db) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningAction.java (.../LearningAction.java) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -25,10 +25,7 @@ package org.lamsfoundation.lams.tool.scribe.web.actions; import java.io.IOException; -import java.util.Iterator; -import java.util.Set; import java.util.TreeMap; -import java.util.TreeSet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,6 +35,7 @@ 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.lamsfoundation.lams.learning.web.util.LearningWebUtil; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; @@ -46,11 +44,9 @@ import org.lamsfoundation.lams.tool.exception.DataMissingException; import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.tool.scribe.dto.ScribeDTO; -import org.lamsfoundation.lams.tool.scribe.dto.ScribeReportEntryDTO; import org.lamsfoundation.lams.tool.scribe.dto.ScribeSessionDTO; import org.lamsfoundation.lams.tool.scribe.dto.ScribeUserDTO; import org.lamsfoundation.lams.tool.scribe.model.Scribe; -import org.lamsfoundation.lams.tool.scribe.model.ScribeReportEntry; import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; import org.lamsfoundation.lams.tool.scribe.service.IScribeService; @@ -70,437 +66,303 @@ * @author * @version * - * @struts.action path="/learning" parameter="dispatch" scope="request" - * name="learningForm" + * @struts.action path="/learning" parameter="dispatch" scope="request" name="learningForm" * @struts.action-forward name="learning" path="tiles:/learning/main" * @struts.action-forward name="scribe" path="tiles:/learning/scribe" * @struts.action-forward name="defineLater" path="tiles:/learning/defineLater" * @struts.action-forward name="waitForScribe" path="tiles:/learning/waitForScribe" * @struts.action-forward name="notebook" path="tiles:/learning/notebook" - * @struts.action-forward name="voteDisplay" path="/pages/parts/voteDisplay.jsp" * @struts.action-forward name="report" path="tiles:/learning/report" - * @struts.action-forward name="instructions" - * path="tiles:/learning/instructions" + * @struts.action-forward name="instructions" path="tiles:/learning/instructions" */ public class LearningAction extends LamsDispatchAction { - private static Logger log = Logger.getLogger(LearningAction.class); + private static Logger log = Logger.getLogger(LearningAction.class); - private static final boolean MODE_OPTIONAL = false; + private static final boolean MODE_OPTIONAL = false; - private IScribeService scribeService; + private IScribeService scribeService; - public ActionForward unspecified(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) - throws Exception { - // 'toolSessionID' and 'mode' paramters are expected to be present. - ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, - AttributeNames.PARAM_MODE, MODE_OPTIONAL); + @Override + public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + // 'toolSessionID' and 'mode' paramters are expected to be present. + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, + LearningAction.MODE_OPTIONAL); - Long toolSessionID = WebUtil.readLongParam(request, - AttributeNames.PARAM_TOOL_SESSION_ID); + Long toolSessionID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); - // set up scribeService - if (scribeService == null) { - scribeService = ScribeServiceProxy.getScribeService(this - .getServlet().getServletContext()); - } - //try to clone scribe heading from content. This method will execute - //for every new learner enter, but the heading only copied once. - try{ - scribeService.createReportEntry(toolSessionID); - } catch (ObjectOptimisticLockingFailureException e) { - log.debug("Multiple learner get into scribe simultaneously. Cloning report entry skipped"); - } + // set up scribeService + if (scribeService == null) { + scribeService = ScribeServiceProxy.getScribeService(this.getServlet().getServletContext()); + } + //try to clone scribe heading from content. This method will execute + //for every new learner enter, but the heading only copied once. + try { + scribeService.createReportEntry(toolSessionID); + } catch (ObjectOptimisticLockingFailureException e) { + LearningAction.log.debug("Multiple learner get into scribe simultaneously. Cloning report entry skipped"); + } - // Retrieve the session and content. - ScribeSession scribeSession = scribeService - .getSessionBySessionId(toolSessionID); - if (scribeSession == null) { - throw new ScribeException( - "Cannot retrieve session with toolSessionID" - + toolSessionID); - } - Scribe scribe = scribeSession.getScribe(); - - // check defineLater - if (scribe.isDefineLater()) { - return mapping.findForward("defineLater"); - } - - // Ensure that the content in use flag is set. - if (!scribe.isContentInUse()) { - scribe.setContentInUse(new Boolean(true)); - scribeService.saveOrUpdateScribe(scribe); - } - - LearningWebUtil.putActivityPositionInRequestByToolSessionId(toolSessionID, request, getServlet() - .getServletContext()); - - // Retrieve the current user - ScribeUser scribeUser = getCurrentUser(toolSessionID); - - // check whether scribe has been appointed - while (scribeSession.getAppointedScribe() == null) { - // check autoSelectScribe - if (scribe.isAutoSelectScribe() == false) { - // learner needs to wait until a scribe has been appointed by - // teacher. - return mapping.findForward("waitForScribe"); - - } else { - // appoint the currentUser as the scribe - scribeSession.setAppointedScribe(scribeUser); - - // attempt to update the scribeSession. - try { - scribeService.saveOrUpdateScribeSession(scribeSession); - } catch (ObjectOptimisticLockingFailureException le) { - // scribeSession has been modified. Reload scribeSession and - // check again. - scribeSession = scribeService - .getSessionBySessionId(toolSessionID); - } - } - } - - // setup dto's forms and attributes. - ((LearningForm) form).setToolSessionID(scribeSession.getSessionId()); - request.setAttribute("MODE", mode.toString()); - setupDTOs(request, scribeSession, scribeUser); - - // check force complete - if (scribeSession.isForceComplete()) { - // go to report page - if ( scribeSession.getScribe().isShowAggregatedReports() ) - setupOtherGroupReportDTO(request, scribeSession, scribeUser); - return mapping.findForward("report"); - } - - // check if user has started activity - if (!scribeUser.isStartedActivity()) { - if (scribeSession.getAppointedScribe().getUid() == scribeUser - .getUid()) { - request.setAttribute("role", "scribe"); - } else { - request.setAttribute("role", "learner"); - } - return mapping.findForward("instructions"); - } - - // check if current user is the scribe. - if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { - return mapping.findForward("scribe"); - } else { - return mapping.findForward("learning"); - } - + // Retrieve the session and content. + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + if (scribeSession == null) { + throw new ScribeException("Cannot retrieve session with toolSessionID" + toolSessionID); } + Scribe scribe = scribeSession.getScribe(); - private ScribeUser getCurrentUser(Long toolSessionID) { - UserDTO user = (UserDTO) SessionManager.getSession().getAttribute( - AttributeNames.USER); - - // attempt to retrieve user using userId and toolSessionID - ScribeUser scribeUser = scribeService.getUserByUserIdAndSessionId( - new Long(user.getUserID().intValue()), toolSessionID); - - if (scribeUser == null) { - ScribeSession scribeSession = scribeService - .getSessionBySessionId(toolSessionID); - scribeUser = scribeService.createScribeUser(user, scribeSession); - } - - return scribeUser; + // check defineLater + if (scribe.isDefineLater()) { + return mapping.findForward("defineLater"); } - public ActionForward startActivity(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { - - LearningForm lrnForm = (LearningForm) form; - Long toolSessionID = lrnForm.getToolSessionID(); - - ScribeSession scribeSession = scribeService - .getSessionBySessionId(toolSessionID); - ScribeUser scribeUser = getCurrentUser(toolSessionID); - - // setup dto's, forms and attributes. - lrnForm.setToolSessionID(scribeSession.getSessionId()); - request.setAttribute("MODE", lrnForm.getMode()); - setupDTOs(request, scribeSession, scribeUser); - - // update scribe user and go to instructions page - scribeUser.setStartedActivity(true); - scribeService.saveOrUpdateScribeUser(scribeUser); - - // check if current user is the scribe. - if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { - return mapping.findForward("scribe"); - } - - return mapping.findForward("learning"); + // Ensure that the content in use flag is set. + if (!scribe.isContentInUse()) { + scribe.setContentInUse(new Boolean(true)); + scribeService.saveOrUpdateScribe(scribe); } - public ActionForward finishActivity(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { + LearningWebUtil.putActivityPositionInRequestByToolSessionId(toolSessionID, request, + getServlet().getServletContext()); - LearningForm lrnForm = (LearningForm) form; + // Retrieve the current user + ScribeUser scribeUser = getCurrentUser(toolSessionID); - // set the finished flag - ScribeUser scribeUser = scribeService.getUserByUID(lrnForm - .getScribeUserUID()); - if (scribeUser != null) { - scribeUser.setFinishedActivity(true); - scribeService.saveOrUpdateScribeUser(scribeUser); - } else { - log.error("finishActivity(): couldn't find ScribeUser with uid: " - + lrnForm.getScribeUserUID()); - } + // check whether scribe has been appointed + while (scribeSession.getAppointedScribe() == null) { + // check autoSelectScribe + if (scribe.isAutoSelectScribe() == false) { + // learner needs to wait until a scribe has been appointed by + // teacher. + return mapping.findForward("waitForScribe"); - ToolSessionManager sessionMgrService = ScribeServiceProxy - .getScribeSessionManager(getServlet().getServletContext()); + } else { + // appoint the currentUser as the scribe + scribeSession.setAppointedScribe(scribeUser); - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - Long userID = new Long(user.getUserID().longValue()); - Long toolSessionID = scribeUser.getScribeSession().getSessionId(); - - String nextActivityUrl; + // attempt to update the scribeSession. try { - nextActivityUrl = sessionMgrService.leaveToolSession(toolSessionID, - userID); - response.sendRedirect(nextActivityUrl); - } catch (DataMissingException e) { - throw new ScribeException(e); - } catch (ToolException e) { - throw new ScribeException(e); - } catch (IOException e) { - throw new ScribeException(e); + scribeService.saveOrUpdateScribeSession(scribeSession); + } catch (ObjectOptimisticLockingFailureException le) { + // scribeSession has been modified. Reload scribeSession and + // check again. + scribeSession = scribeService.getSessionBySessionId(toolSessionID); } - - return null; // TODO need to return proper page. + } } - public ActionForward openNotebook(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { + // setup dto's forms and attributes. + ((LearningForm) form).setToolSessionID(scribeSession.getSessionId()); + request.setAttribute("MODE", mode.toString()); + setupDTOs(request, scribeSession, scribeUser); - LearningForm lrnForm = (LearningForm) form; + // check force complete + if (scribeSession.isForceComplete()) { + // go to report page + if (scribeSession.getScribe().isShowAggregatedReports()) { + setupOtherGroupReportDTO(request, scribeSession, scribeUser); + } + return mapping.findForward("report"); + } - // set the finished flag - ScribeUser scribeUser = scribeService.getUserByUID(lrnForm - .getScribeUserUID()); - ScribeDTO scribeDTO = new ScribeDTO(scribeUser.getScribeSession() - .getScribe()); + // check if user has started activity + if (!scribeUser.isStartedActivity()) { + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + request.setAttribute("role", "scribe"); + } else { + request.setAttribute("role", "learner"); + } + return mapping.findForward("instructions"); + } - request.setAttribute("scribeDTO", scribeDTO); - - LearningWebUtil.putActivityPositionInRequestByToolSessionId(scribeUser.getScribeSession().getSessionId(), - request, getServlet().getServletContext()); - - return mapping.findForward("notebook"); + // check if current user is the scribe. + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + return mapping.findForward("scribe"); + } else { + return mapping.findForward("learning"); } - public ActionForward submitReflection(ActionMapping mapping, - ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + } - // save the reflection entry and call the notebook. + private ScribeUser getCurrentUser(Long toolSessionID) { + UserDTO user = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); - LearningForm lrnForm = (LearningForm) form; + // attempt to retrieve user using userId and toolSessionID + ScribeUser scribeUser = scribeService.getUserByUserIdAndSessionId(new Long(user.getUserID().intValue()), + toolSessionID); - ScribeUser scribeUser = scribeService.getUserByUID(lrnForm - .getScribeUserUID()); - - scribeService.createNotebookEntry(scribeUser.getScribeSession() - .getSessionId(), CoreNotebookConstants.NOTEBOOK_TOOL, - ScribeConstants.TOOL_SIGNATURE, scribeUser.getUserId() - .intValue(), lrnForm.getEntryText()); - - return finishActivity(mapping, form, request, response); + if (scribeUser == null) { + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + scribeUser = scribeService.createScribeUser(user, scribeSession); } - public ActionForward submitReport(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { + return scribeUser; + } - LearningForm lrnForm = (LearningForm) form; - Long toolSessionID = lrnForm.getToolSessionID(); + public ActionForward startActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - ScribeSession session = scribeService - .getSessionBySessionId(toolSessionID); + LearningForm lrnForm = (LearningForm) form; + Long toolSessionID = lrnForm.getToolSessionID(); - ScribeUser scribeUser = getCurrentUser(toolSessionID); + ScribeSession scribeSession = scribeService.getSessionBySessionId(toolSessionID); + ScribeUser scribeUser = getCurrentUser(toolSessionID); - boolean reportValid = false; + // setup dto's, forms and attributes. + lrnForm.setToolSessionID(scribeSession.getSessionId()); + request.setAttribute("MODE", lrnForm.getMode()); + setupDTOs(request, scribeSession, scribeUser); - for (Iterator iter = session.getScribeReportEntries().iterator(); iter - .hasNext();) { - ScribeReportEntry report = (ScribeReportEntry) iter.next(); + // update scribe user and go to instructions page + scribeUser.setStartedActivity(true); + scribeService.saveOrUpdateScribeUser(scribeUser); - String entryText = (String) lrnForm.getReport(report.getUid() - .toString()); + // check if current user is the scribe. + if (scribeSession.getAppointedScribe().getUid() == scribeUser.getUid()) { + return mapping.findForward("scribe"); + } - if (entryText.length() != 0) { - reportValid = true; - } - } + return mapping.findForward("learning"); + } - if (reportValid) { - // update scribeReports - for (Iterator iter = session.getScribeReportEntries().iterator(); iter - .hasNext();) { - ScribeReportEntry report = (ScribeReportEntry) iter.next(); + public ActionForward finishActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - String entryText = (String) lrnForm.getReport(report.getUid() - .toString()); - report.setEntryText(entryText); - } + LearningForm lrnForm = (LearningForm) form; - // persist changes - for (Iterator iter = session.getScribeUsers().iterator(); iter - .hasNext();) { - ScribeUser user = (ScribeUser) iter.next(); - user.setReportApproved(false); - scribeService.saveOrUpdateScribeUser(scribeUser); - } + // set the finished flag + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + if (scribeUser != null) { + scribeUser.setFinishedActivity(true); + scribeService.saveOrUpdateScribeUser(scribeUser); + } else { + LearningAction.log + .error("finishActivity(): couldn't find ScribeUser with uid: " + lrnForm.getScribeUserUID()); + } - session.setReportSubmitted(true); - scribeService.saveOrUpdateScribeSession(session); - } + ToolSessionManager sessionMgrService = ScribeServiceProxy + .getScribeSessionManager(getServlet().getServletContext()); - request.setAttribute("MODE", lrnForm.getMode()); - setupDTOs(request, session, scribeUser); + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + Long toolSessionID = scribeUser.getScribeSession().getSessionId(); - return mapping.findForward("scribe"); + String nextActivityUrl; + try { + nextActivityUrl = sessionMgrService.leaveToolSession(toolSessionID, userID); + response.sendRedirect(nextActivityUrl); + } catch (DataMissingException e) { + throw new ScribeException(e); + } catch (ToolException e) { + throw new ScribeException(e); + } catch (IOException e) { + throw new ScribeException(e); } - public ActionForward submitApproval(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { + return null; // TODO need to return proper page. + } - LearningForm lrnForm = (LearningForm) form; + public ActionForward openNotebook(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - // get session and user - ScribeSession session = scribeService.getSessionBySessionId(lrnForm - .getToolSessionID()); - ScribeUser scribeUser = getCurrentUser(session.getSessionId()); + LearningForm lrnForm = (LearningForm) form; - scribeUser.setReportApproved(true); + // set the finished flag + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + ScribeDTO scribeDTO = new ScribeDTO(scribeUser.getScribeSession().getScribe()); - request.setAttribute("MODE", lrnForm.getMode()); - setupDTOs(request, session, scribeUser); + request.setAttribute("scribeDTO", scribeDTO); - scribeService.saveOrUpdateScribeUser(scribeUser); + LearningWebUtil.putActivityPositionInRequestByToolSessionId(scribeUser.getScribeSession().getSessionId(), + request, getServlet().getServletContext()); - if (session.getAppointedScribe().equals(scribeUser)) { - // send updated voteDisplay - return getVoteDisplay(mapping, form, request, response); - } else { - // load learning page. - return mapping.findForward("learning"); - } - } + return mapping.findForward("notebook"); + } - public ActionForward getVoteDisplay(ActionMapping mapping, ActionForm form, - HttpServletRequest request, HttpServletResponse response) { + public ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - Long toolSessionID = WebUtil.readLongParam(request, "toolSessionID"); + // save the reflection entry and call the notebook. - ScribeSession session = scribeService - .getSessionBySessionId(toolSessionID); + LearningForm lrnForm = (LearningForm) form; - int numberOfVotes = 0; + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); - for (Iterator iter = session.getScribeUsers().iterator(); iter - .hasNext();) { - ScribeUser user = (ScribeUser) iter.next(); + scribeService.createNotebookEntry(scribeUser.getScribeSession().getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, scribeUser.getUserId().intValue(), + lrnForm.getEntryText()); - if (user.isReportApproved()) { - numberOfVotes++; - } - } + return finishActivity(mapping, form, request, response); + } - int numberOfLearners = session.getScribeUsers().size(); - int votePercentage = ScribeUtils.calculateVotePercentage(numberOfVotes, - numberOfLearners); + public ActionForward forceCompleteActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws JSONException, IOException { + LearningForm lrnForm = (LearningForm) form; + ScribeUser scribeUser = scribeService.getUserByUID(lrnForm.getScribeUserUID()); + ScribeSession session = scribeUser.getScribeSession(); - ScribeSessionDTO sessionDTO = new ScribeSessionDTO(); - sessionDTO.setNumberOfVotes(numberOfVotes); - sessionDTO.setNumberOfLearners(numberOfLearners); - sessionDTO.setVotePercentage(votePercentage); - - request.setAttribute("scribeSessionDTO", sessionDTO); - - return mapping.findForward("voteDisplay"); + if (session.getAppointedScribe().getUid() == scribeUser.getUid()) { + session.setForceComplete(true); + } else { + // TODO need to implement this. + LearningAction.log + .error("ScribeUserUID: " + scribeUser.getUid() + " is not allowed to forceComplete this session"); } - public ActionForward forceCompleteActivity(ActionMapping mapping, - ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + request.setAttribute("MODE", lrnForm.getMode()); + setupDTOs(request, session, scribeUser); + scribeService.saveOrUpdateScribeUser(scribeUser); - LearningForm lrnForm = (LearningForm) form; + LearningWebsocketServer.sendCloseRequest(session.getSessionId()); - ScribeUser scribeUser = scribeService.getUserByUID(lrnForm - .getScribeUserUID()); + if (session.getScribe().isShowAggregatedReports()) { + setupOtherGroupReportDTO(request, session, scribeUser); + } - ScribeSession session = scribeUser.getScribeSession(); + LearningWebUtil.putActivityPositionInRequestByToolSessionId(session.getSessionId(), request, + getServlet().getServletContext()); - if (session.getAppointedScribe().getUid() == scribeUser.getUid()) { - session.setForceComplete(true); - } else { - // TODO need to implement this. - log.error("ScribeUserUID: " + scribeUser.getUid() - + " is not allowed to forceComplete this session"); - } + return mapping.findForward("report"); + } - request.setAttribute("MODE", lrnForm.getMode()); - setupDTOs(request, session, scribeUser); + // Private methods. - scribeService.saveOrUpdateScribeUser(scribeUser); + /** + * Set up all the DTO relating to this session. Doesn't set up the DTO containing the reports of the other groups. + */ + private void setupDTOs(HttpServletRequest request, ScribeSession scribeSession, ScribeUser scribeUser) { - if ( session.getScribe().isShowAggregatedReports() ) - setupOtherGroupReportDTO(request, session, scribeUser); - - LearningWebUtil.putActivityPositionInRequestByToolSessionId(session.getSessionId(), request, getServlet() - .getServletContext()); + ScribeDTO scribeDTO = new ScribeDTO(scribeSession.getScribe()); + request.setAttribute("scribeDTO", scribeDTO); - return mapping.findForward("report"); + ScribeSessionDTO sessionDTO = new ScribeSessionDTO(scribeSession); + request.setAttribute("scribeSessionDTO", sessionDTO); + + ScribeUserDTO scribeUserDTO = new ScribeUserDTO(scribeUser); + if (scribeUser.isFinishedActivity()) { + // get the notebook entry. + NotebookEntry notebookEntry = scribeService.getEntry(scribeSession.getSessionId(), + CoreNotebookConstants.NOTEBOOK_TOOL, ScribeConstants.TOOL_SIGNATURE, + scribeUser.getUserId().intValue()); + if (notebookEntry != null) { + scribeUserDTO.notebookEntry = notebookEntry.getEntry(); + } } + request.setAttribute("scribeUserDTO", scribeUserDTO); + } - // Private methods. - - /** Set up all the DTO relating to this session. Doesn't set up the DTO containing the reports of the other groups. */ - private void setupDTOs(HttpServletRequest request, - ScribeSession scribeSession, ScribeUser scribeUser) { - - ScribeDTO scribeDTO = new ScribeDTO(scribeSession.getScribe()); - request.setAttribute("scribeDTO", scribeDTO); - - ScribeSessionDTO sessionDTO = ScribeUtils.createSessionDTO(scribeSession); - request.setAttribute("scribeSessionDTO", sessionDTO); - - ScribeUserDTO scribeUserDTO = new ScribeUserDTO(scribeUser); - if (scribeUser.isFinishedActivity()) { - // get the notebook entry. - NotebookEntry notebookEntry = scribeService.getEntry(scribeSession - .getSessionId(), CoreNotebookConstants.NOTEBOOK_TOOL, - ScribeConstants.TOOL_SIGNATURE, scribeUser.getUserId() - .intValue()); - if (notebookEntry != null) { - scribeUserDTO.notebookEntry = notebookEntry.getEntry(); - } - } - request.setAttribute("scribeUserDTO", scribeUserDTO); + /** + * Create a map of the reports (in ScribeSessionDTO format) for all the other groups/sessions, where the key is the + * group/session name. The code ensures that the session name is unique, adding the session id if necessary. It will + * only include the finalized reports. + */ + private void setupOtherGroupReportDTO(HttpServletRequest request, ScribeSession scribeSession, + ScribeUser scribeUser) { + TreeMap otherScribeSessions = ScribeUtils.getReportDTOs(scribeSession); + if (otherScribeSessions.size() > 0) { + request.setAttribute("otherScribeSessions", otherScribeSessions.values()); } - - /** Create a map of the reports (in ScribeSessionDTO format) for all the other groups/sessions, where the key - * is the group/session name. The code ensures that the session name is unique, adding the session id if necessary. - * It will only include the finalized reports. */ - private void setupOtherGroupReportDTO(HttpServletRequest request, - ScribeSession scribeSession, ScribeUser scribeUser) { - TreeMap otherScribeSessions = ScribeUtils.getReportDTOs(scribeSession); - if ( otherScribeSessions.size() > 0 ) { - request.setAttribute("otherScribeSessions", otherScribeSessions.values()); - } - } + } - } Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java =================================================================== diff -u --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java (revision 0) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/LearningWebsocketServer.java (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -0,0 +1,316 @@ +package org.lamsfoundation.lams.tool.scribe.web.actions; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +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.scribe.model.ScribeReportEntry; +import org.lamsfoundation.lams.tool.scribe.model.ScribeSession; +import org.lamsfoundation.lams.tool.scribe.model.ScribeUser; +import org.lamsfoundation.lams.tool.scribe.service.IScribeService; +import org.lamsfoundation.lams.tool.scribe.service.ScribeServiceProxy; +import org.lamsfoundation.lams.tool.scribe.util.ScribeUtils; +import org.lamsfoundation.lams.util.hibernate.HibernateSessionManager; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** + * Receives, processes and sends Scribe reports and votes to Learners. + * + * @author Marcin Cieslak + */ +@ServerEndpoint("/learningWebsocket") +public class LearningWebsocketServer { + + // caches what was sent to users already so it can be compared with DB + private static class ScribeSessionCache { + private int numberOfVotes = 0; + private int numberOfLearners = 0; + private final Map reports = new TreeMap(); + } + + /** + * A singleton which updates Learners with reports and votes. + */ + 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 { + // synchronize websockets as a new Learner entering the activity could modify this collection + synchronized (LearningWebsocketServer.websockets) { + 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(); + try { + send(toolSessionId, null); + } catch (JSONException e) { + LearningWebsocketServer.log.error("Error while building Scribe report JSON", e); + } + // if all learners left the activity, remove the obsolete mapping + Set sessionWebsockets = entry.getValue(); + if (sessionWebsockets.isEmpty()) { + entryIterator.remove(); + LearningWebsocketServer.cache.remove(toolSessionId); + } + } + } + + Thread.sleep(SendWorker.CHECK_INTERVAL); + } catch (InterruptedException e) { + LearningWebsocketServer.log.warn("Stopping Scribe worker thread"); + stopFlag = true; + } catch (Exception e) { + // error caught, but carry on + LearningWebsocketServer.log.error("Error in Scribe worker thread", e); + } + } + } + + /** + * Feeds websockets with reports and votes. + */ + @SuppressWarnings("unchecked") + private void send(Long toolSessionId, Session newWebsocket) throws JSONException, IOException { + JSONObject responseJSON = new JSONObject(); + ScribeSessionCache sessionCache = LearningWebsocketServer.cache.get(toolSessionId); + if (sessionCache == null) { + // first time run, create the cache + sessionCache = new ScribeSessionCache(); + LearningWebsocketServer.cache.put(toolSessionId, sessionCache); + } + + // websocket communication bypasses standard HTTP filters, so Hibernate session needs to be initialised manually + // A new session needs to be created on each thread run as the session keeps stale Hibernate data (single transaction). + HibernateSessionManager.bindHibernateSessionToCurrentThread(true); + + boolean send = false; + ScribeSession scribeSession = LearningWebsocketServer.getScribeService() + .getSessionBySessionId(toolSessionId); + Set learners = scribeSession.getScribeUsers(); + if (sessionCache.numberOfLearners != learners.size()) { + // new users have arrived + sessionCache.numberOfLearners = learners.size(); + send = true; + } + + // collect users who agreed on the report + Set learnersApproved = new TreeSet(); + for (ScribeUser user : learners) { + if (user.isReportApproved()) { + learnersApproved.add(user.getLoginName()); + } + } + if (sessionCache.numberOfVotes != learnersApproved.size()) { + sessionCache.numberOfVotes = learnersApproved.size(); + send = true; + } + + JSONArray reportsJSON = new JSONArray(); + synchronized (sessionCache) { + for (ScribeReportEntry storedReport : (Set) scribeSession.getScribeReportEntries()) { + Long uid = storedReport.getUid(); + String cachedReportText = sessionCache.reports.get(uid); + String storedReportText = storedReport.getEntryText(); + if (cachedReportText == null ? storedReportText != null + : (storedReportText == null) || (cachedReportText.length() != storedReportText.length()) + || !cachedReportText.equals(storedReportText)) { + // we could be storing hash instead of full report + // but to build hash each report char needs to be processed anyway + sessionCache.reports.put(uid, storedReportText); + + JSONObject reportJSON = new JSONObject(); + reportJSON.put("uid", uid); + reportJSON.put("text", storedReportText); + reportsJSON.put(reportJSON); + } + } + } + if (reportsJSON.length() > 0) { + responseJSON.put("reports", reportsJSON); + send = true; + } + + // always send to an user who just entered, otherwise only if there is new data + if (!send && (newWebsocket == null)) { + return; + } + + responseJSON.put("numberOfLearners", sessionCache.numberOfLearners); + responseJSON.put("numberOfVotes", sessionCache.numberOfVotes); + int votePercentage = ScribeUtils.calculateVotePercentage(sessionCache.numberOfVotes, + sessionCache.numberOfLearners); + responseJSON.put("votePercentage", votePercentage); + + // either send only to the new user or to everyone + if (newWebsocket == null) { + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + // synchronize websockets as a new Learner entering Scribe could modify this collection + synchronized (sessionWebsockets) { + for (Session websocket : sessionWebsockets) { + String userName = websocket.getUserPrincipal().getName(); + responseJSON.put("approved", learnersApproved.contains(userName)); + websocket.getBasicRemote().sendText(responseJSON.toString()); + } + } + } else { + String userName = newWebsocket.getUserPrincipal().getName(); + responseJSON.put("approved", learnersApproved.contains(userName)); + newWebsocket.getBasicRemote().sendText(responseJSON.toString()); + } + } + } + + private static Logger log = Logger.getLogger(LearningWebsocketServer.class); + + private static IScribeService scribeService; + + private static final SendWorker sendWorker = new SendWorker(); + // maps toolSessionId -> cached session data + private static final Map cache = Collections + .synchronizedMap(new TreeMap()); + private static final Map> websockets = Collections + .synchronizedMap(new TreeMap>()); + + 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)); + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + if (sessionWebsockets == null) { + sessionWebsockets = Collections.synchronizedSet(new HashSet()); + LearningWebsocketServer.websockets.put(toolSessionId, sessionWebsockets); + } + sessionWebsockets.add(websocket); + + if (LearningWebsocketServer.log.isDebugEnabled()) { + LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + + " entered Scribe with toolSessionId: " + toolSessionId); + } + + LearningWebsocketServer.sendWorker.send(toolSessionId, websocket); + } + + /** + * 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 Scribe 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; + } + JSONObject requestJSON = new JSONObject(input); + switch (requestJSON.getString("type")) { + case "vote": + LearningWebsocketServer.vote(websocket); + break; + case "submitReport": + LearningWebsocketServer.submitReport(requestJSON, websocket); + break; + } + } + + /** + * User has approved a report. + */ + private static void vote(Session websocket) { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + String userName = websocket.getUserPrincipal().getName(); + ScribeUser learner = LearningWebsocketServer.getScribeService().getUserByLoginNameAndSessionId(userName, + toolSessionId); + if (learner != null) { + learner.setReportApproved(true); + getScribeService().saveOrUpdateScribeUser(learner); + } + } + + /** + * The scribe has submitted a report. + */ + private static void submitReport(JSONObject requestJSON, Session websocket) throws JSONException { + Long toolSessionId = Long + .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); + String userName = websocket.getUserPrincipal().getName(); + LearningWebsocketServer.getScribeService().submitReport(toolSessionId, userName, requestJSON); + } + + /** + * The scribe or a Monitor has force completed the activity. Browsers will refresh and display report summary. + */ + static void sendCloseRequest(Long toolSessionId) throws JSONException, IOException { + JSONObject responseJSON = new JSONObject(); + responseJSON.put("close", true); + String response = responseJSON.toString(); + + Set sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); + synchronized (sessionWebsockets) { + for (Session websocket : sessionWebsockets) { + websocket.getBasicRemote().sendText(response); + } + } + } + + private static IScribeService getScribeService() { + if (LearningWebsocketServer.scribeService == null) { + LearningWebsocketServer.scribeService = ScribeServiceProxy + .getScribeService(SessionManager.getServletContext()); + } + return LearningWebsocketServer.scribeService; + } +} \ No newline at end of file Index: lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/MonitoringAction.java =================================================================== diff -u -r1da8dadde28e6b4b1f248175bb9f3c22ffeeb9cf -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision 1da8dadde28e6b4b1f248175bb9f3c22ffeeb9cf) +++ lams_tool_scribe/src/java/org/lamsfoundation/lams/tool/scribe/web/actions/MonitoringAction.java (.../MonitoringAction.java) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -24,6 +24,7 @@ package org.lamsfoundation.lams.tool.scribe.web.actions; +import java.io.IOException; import java.util.Iterator; import javax.servlet.http.HttpServletRequest; @@ -33,6 +34,7 @@ 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.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.tool.scribe.dto.ScribeDTO; @@ -136,14 +138,16 @@ } public ActionForward forceCompleteActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + HttpServletResponse response) throws JSONException, IOException { MonitoringForm monForm = (MonitoringForm) form; ScribeSession session = scribeService.getSessionBySessionId(monForm.getToolSessionID()); session.setForceComplete(true); scribeService.saveOrUpdateScribeSession(session); + LearningWebsocketServer.sendCloseRequest(session.getSessionId()); + ScribeDTO scribeDTO = setupScribeDTO(session.getScribe()); request.setAttribute("monitoringDTO", scribeDTO); request.setAttribute("contentFolderID", monForm.getContentFolderID()); Fisheye: Tag e1312708b95d2a0343c95cadbf03432d65c7657c refers to a dead (removed) revision in file `lams_tool_scribe/web/includes/javascript/learning.js'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_scribe/web/pages/learning/learning.jsp =================================================================== diff -u -r276c03eb13322c40ee4c9cc63d0e34d8c371c68a -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/web/pages/learning/learning.jsp (.../learning.jsp) (revision 276c03eb13322c40ee4c9cc63d0e34d8c371c68a) +++ lams_tool_scribe/web/pages/learning/learning.jsp (.../learning.jsp) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -8,12 +8,58 @@ - + @@ -32,10 +78,6 @@

: ${appointedScribe}

- - - - @@ -46,36 +88,29 @@
- - + - - - - - - + + + +
- -
-
- - - -
+
+
+
- +
- - - + \ No newline at end of file Index: lams_tool_scribe/web/pages/learning/scribe.jsp =================================================================== diff -u -r276c03eb13322c40ee4c9cc63d0e34d8c371c68a -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/web/pages/learning/scribe.jsp (.../scribe.jsp) (revision 276c03eb13322c40ee4c9cc63d0e34d8c371c68a) +++ lams_tool_scribe/web/pages/learning/scribe.jsp (.../scribe.jsp) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -7,44 +7,83 @@ - - + @@ -54,68 +93,55 @@
- - - - +
+ <%@include file="/pages/parts/voteDisplay.jsp"%> +
-
- <%@include file="/pages/parts/voteDisplay.jsp"%> -
+

+ + +

+ +
+
+
+
+ +
+
-

- - -

- - - -
-
-
-
- -
-
+
+ - -
- - - - - - -
-
- - - - - - + + + +
+ + + +
- +
+
- -
-
- - - -
+ +
+
+
- +
+
- -
@@ -131,22 +157,12 @@
- -
- - -
-
+
+ + +
- - - - - + \ No newline at end of file Index: lams_tool_scribe/web/pages/parts/voteDisplay.jsp =================================================================== diff -u -r276c03eb13322c40ee4c9cc63d0e34d8c371c68a -re1312708b95d2a0343c95cadbf03432d65c7657c --- lams_tool_scribe/web/pages/parts/voteDisplay.jsp (.../voteDisplay.jsp) (revision 276c03eb13322c40ee4c9cc63d0e34d8c371c68a) +++ lams_tool_scribe/web/pages/parts/voteDisplay.jsp (.../voteDisplay.jsp) (revision e1312708b95d2a0343c95cadbf03432d65c7657c) @@ -1,15 +1,17 @@ <%@ include file="/common/taglibs.jsp"%>
-
${scribeSessionDTO.votePercentage}% -
- - - - - (${scribeSessionDTO.votePercentage}%) +
+ + + + + + + (${scribeSessionDTO.votePercentage}%)