Index: lams_build/conf/unix/jboss/service/treecache.xml =================================================================== RCS file: /usr/local/cvsroot/lams_build/conf/unix/jboss/service/treecache.xml,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_build/conf/unix/jboss/service/treecache.xml 13 May 2009 09:37:55 -0000 1.1.2.1 +++ lams_build/conf/unix/jboss/service/treecache.xml 25 May 2009 18:16:20 -0000 1.1.2.2 @@ -3,14 +3,17 @@ - + + - - - Index: lams_build/conf/windows/jboss/service/treecache.xml =================================================================== RCS file: /usr/local/cvsroot/lams_build/conf/windows/jboss/service/treecache.xml,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_build/conf/windows/jboss/service/treecache.xml 13 May 2009 09:37:57 -0000 1.1.2.1 +++ lams_build/conf/windows/jboss/service/treecache.xml 25 May 2009 18:16:20 -0000 1.1.2.2 @@ -14,9 +14,6 @@ - - - Index: lams_common/src/java/org/lamsfoundation/lams/applicationContext.xml =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/applicationContext.xml,v diff -u -r1.7.4.1 -r1.7.4.2 --- lams_common/src/java/org/lamsfoundation/lams/applicationContext.xml 13 May 2009 10:05:21 -0000 1.7.4.1 +++ lams_common/src/java/org/lamsfoundation/lams/applicationContext.xml 25 May 2009 18:16:14 -0000 1.7.4.2 @@ -20,6 +20,8 @@ 20 1800 50 + org.hibernate.transaction.JBossTransactionManagerLookup + true org.hibernate.cache.jbc2.SharedJBossCacheRegionFactory + @@ -53,6 +56,8 @@ - + + + \ No newline at end of file Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java,v diff -u -r1.96.4.3.2.1 -r1.96.4.3.2.2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java 21 May 2009 15:25:44 -0000 1.96.4.3.2.1 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java 25 May 2009 18:16:03 -0000 1.96.4.3.2.2 @@ -560,7 +560,7 @@ * lesson id * @return the updated learner progress */ - public LearnerProgress completeActivity(Integer learnerId, Activity activity, LearnerProgress progress) { + public synchronized LearnerProgress completeActivity(Integer learnerId, Activity activity, LearnerProgress progress) { LearnerProgress nextLearnerProgress = null; // Need to synchronise the next bit of code so that if the tool calls Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java,v diff -u -r1.27.2.2 -r1.27.2.2.2.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java 1 May 2009 03:00:14 -0000 1.27.2.2 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java 25 May 2009 18:16:04 -0000 1.27.2.2.2.1 @@ -48,6 +48,7 @@ import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.dao.CannotAcquireLockException; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -61,17 +62,16 @@ public class LearningWebUtil { private static Logger log = Logger.getLogger(LearningWebUtil.class); - //--------------------------------------------------------------------- + // --------------------------------------------------------------------- // Class level constants - session attributes - //--------------------------------------------------------------------- + // --------------------------------------------------------------------- public static final String PARAM_PROGRESS_ID = "progressID"; - // public static final String POPUP_WINDOW_NAME = "LearnerActivity"; - // public static final String LEARNER_WINDOW_NAME = "lWindow"; + // public static final String POPUP_WINDOW_NAME = "LearnerActivity"; + // public static final String LEARNER_WINDOW_NAME = "lWindow"; /** - * Helper method to retrieve the user data. Gets the id from the user - * details in the shared session + * Helper method to retrieve the user data. Gets the id from the user details in the shared session * * @return the user id */ @@ -82,8 +82,8 @@ } /** - * Helper method to retrieve the user data. Gets the id from the user - * details in the shared session then retrieves the real user object. + * Helper method to retrieve the user data. Gets the id from the user details in the shared session then retrieves + * the real user object. */ public static User getUser(ICoreLearnerService learnerService) { HttpSession ss = SessionManager.getSession(); @@ -93,9 +93,8 @@ } /** - * Put the learner progress in the request. This allows some optimisation - * between the code that updates the progress and the next action which will - * access the progress. + * Put the learner progress in the request. This allows some optimisation between the code that updates the progress + * and the next action which will access the progress. */ public static void putLearnerProgressInRequest(HttpServletRequest request, LearnerProgress progress) { if (progress != null) { @@ -106,22 +105,20 @@ } /** - * Get the current learner progress. Check the request - in some cases it - * may be there. + * Get the current learner progress. Check the request - in some cases it may be there. * - * If not, the learner progress id might be in the request (if we've just - * come from complete activity). If so, get it from the db using the learner - * progress. + * If not, the learner progress id might be in the request (if we've just come from complete activity). If so, get + * it from the db using the learner progress. * - * If the learner progress id isn't available, then we have to look it up - * using activity based on the activity / activity id in the request. + * If the learner progress id isn't available, then we have to look it up using activity based on the activity / + * activity id in the request. */ public static LearnerProgress getLearnerProgress(HttpServletRequest request, ICoreLearnerService learnerService) { LearnerProgress learnerProgress = (LearnerProgress) request .getAttribute(ActivityAction.LEARNER_PROGRESS_REQUEST_ATTRIBUTE); if (learnerProgress != null) { - if (log.isDebugEnabled()) { - log.debug("getLearnerProgress: found progress in the request"); + if (LearningWebUtil.log.isDebugEnabled()) { + LearningWebUtil.log.debug("getLearnerProgress: found progress in the request"); } return learnerProgress; } @@ -131,14 +128,16 @@ // temp hack until Flash side updates it call. if (learnerProgressId == null) { learnerProgressId = WebUtil.readLongParam(request, "progressId", true); - if (learnerProgressId != null) - log.warn("Flash client still using progressId, instead of progressID in a learner call"); + if (learnerProgressId != null) { + LearningWebUtil.log + .warn("Flash client still using progressId, instead of progressID in a learner call"); + } } if (learnerProgressId != null) { learnerProgress = learnerService.getProgressById(new Long(learnerProgressId)); - if (learnerProgress != null && log.isDebugEnabled()) { - log.debug("getLearnerProgress: found progress via progress id"); + if (learnerProgress != null && LearningWebUtil.log.isDebugEnabled()) { + LearningWebUtil.log.debug("getLearnerProgress: found progress via progress id"); } } @@ -149,8 +148,8 @@ Activity act = getActivityFromRequest(request, learnerService); Lesson lesson = learnerService.getLessonByActivity(act); learnerProgress = learnerService.getProgress(learnerId, lesson.getLessonId()); - if (learnerProgress != null && log.isDebugEnabled()) { - log.debug("getLearnerProgress: found progress via learner id and activity"); + if (learnerProgress != null && LearningWebUtil.log.isDebugEnabled()) { + LearningWebUtil.log.debug("getLearnerProgress: found progress via learner id and activity"); } } @@ -159,9 +158,8 @@ } /** - * Get the activity from request. We assume there is a parameter coming in - * if there is no activity can be found in the http request. Then the - * activity id parameter is used to retrieve from database. + * Get the activity from request. We assume there is a parameter coming in if there is no activity can be found in + * the http request. Then the activity id parameter is used to retrieve from database. * * @param request * @return @@ -183,9 +181,8 @@ } /** - * Put an activity into the request. Calls LearnerService to get the - * activity, to ensure that it is a "real" activity, not one of the cglib - * proxies. activity. + * Put an activity into the request. Calls LearnerService to get the activity, to ensure that it is a "real" + * activity, not one of the cglib proxies. activity. * * @param request * @param activity @@ -201,18 +198,16 @@ } /** - * "Complete" an activity from the web layer's perspective. Used for - * CompleteActivityAction and the Gate and Grouping actions. Calls the - * learningService to actually complete the activity and progress. + * "Complete" an activity from the web layer's perspective. Used for CompleteActivityAction and the Gate and + * Grouping actions. Calls the learningService to actually complete the activity and progress. * * @param redirect - * Should this call redirect to the next screen (true) or use - * a forward (false) + * Should this call redirect to the next screen (true) or use a forward (false) * @param windowName - * Name of the window that triggered this code. Normally - * LearnerActivity (the popup window) or lWindow (normal - * learner window) + * Name of the window that triggered this code. Normally LearnerActivity (the popup window) or + * lWindow (normal learner window) * @throws UnsupportedEncodingException + * @throws InterruptedException * */ public static ActionForward completeActivity(HttpServletRequest request, HttpServletResponse response, @@ -228,12 +223,24 @@ } else if (progress.getCompletedActivities().containsKey(currentActivity)) { return actionMappings.getCloseForward(currentActivity, lesson.getLessonId()); } else { - // Set activity as complete - progress = learnerService.completeActivity(learnerId, currentActivity, progress); + // Set activity as complete; synchronized and repeated because of deadlock exceptions + try { + progress = learnerService.completeActivity(learnerId, currentActivity, progress); + } catch (CannotAcquireLockException e) { + LearningWebUtil.log.warn("Can not acquire lock to complete activity " + currentActivity.getActivityId() + + " by learner " + learnerId + ". Retrying..."); + try { + Thread.sleep(2000); + } catch (InterruptedException e1) { + // do nothing, it does not hurt us... + } + progress = learnerService.completeActivity(learnerId, currentActivity, progress); + } } - if (currentActivity != null && currentActivity.isFloating()) + if (currentActivity != null && currentActivity.isFloating()) { return actionMappings.getCloseForward(currentActivity, lesson.getLessonId()); + } LearningWebUtil.putActivityInRequest(request, progress.getNextActivity(), learnerService); LearningWebUtil.putLearnerProgressInRequest(request, progress); @@ -267,19 +274,20 @@ activityForm.setLessonID(currentLesson.getLessonId()); LearningDesign currentDesign = currentLesson.getLearningDesign(); - if (currentDesign != null) + if (currentDesign != null) { activityForm.setVersion(currentDesign.getDesignVersion()); + } } - if (log.isDebugEnabled()) - log.debug("Entering activity: progress summary is " + activityForm.getProgressSummary()); + if (LearningWebUtil.log.isDebugEnabled()) { + LearningWebUtil.log.debug("Entering activity: progress summary is " + activityForm.getProgressSummary()); + } } /** - * Setup the progress string, version and lesson id in the actionForm. The - * values will go in the map with the keys "progressSummary", "lessonID", - * "version". + * Setup the progress string, version and lesson id in the actionForm. The values will go in the map with the keys + * "progressSummary", "lessonID", "version". */ public static void setupProgressInRequest(DynaActionForm actionForm, HttpServletRequest request, LearnerProgress learnerProgress) { @@ -299,12 +307,14 @@ actionForm.set("lessonID", currentLesson.getLessonId()); LearningDesign currentDesign = currentLesson.getLearningDesign(); - if (currentDesign != null) + if (currentDesign != null) { actionForm.set("version", currentDesign.getDesignVersion()); + } } - if (log.isDebugEnabled()) - log.debug("Entering activity: progress summary is " + actionForm.get("progressSummary")); + if (LearningWebUtil.log.isDebugEnabled()) { + LearningWebUtil.log.debug("Entering activity: progress summary is " + actionForm.get("progressSummary")); + } } Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java,v diff -u -r1.99.4.3 -r1.99.4.3.2.1 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java 1 May 2009 06:13:56 -0000 1.99.4.3 +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/service/ForumService.java 25 May 2009 18:16:30 -0000 1.99.4.3.2.1 @@ -250,7 +250,7 @@ MessageSeq msgSeq = messageSeqDao.getByTopicId(message.getUid()); Message root = msgSeq.getRootMessage(); // update reply date - //messageDao.saveOrUpdate(root); // do not update date of root posting + // messageDao.saveOrUpdate(root); // do not update date of root posting return message; } @@ -332,7 +332,7 @@ root.setLastReplyDate(new Date()); // update reply message number for root root.setReplyNumber(root.getReplyNumber() + 1); - //messageDao.saveOrUpdate(root); // do not update the date of root posting + // messageDao.saveOrUpdate(root); // do not update the date of root posting return replyMessage; } @@ -358,8 +358,8 @@ } /** - * This method deletes the content with the given uuid and - * versionID from the content repository + * This method deletes the content with the given uuid and versionID from the content + * repository * * @param uuid * The uuid of the node to be deleted @@ -554,7 +554,7 @@ } } - List users = (List) getUsersBySessionId(sessionID); + List users = getUsersBySessionId(sessionID); if (users != null) { for (ForumUser user : users) { // send marks to gradebook where applicable @@ -625,12 +625,11 @@ } /** - * This method verifies the credentials of the SubmitFiles Tool and gives it - * the Ticket to login and access the Content Repository. + * This method verifies the credentials of the SubmitFiles Tool and gives it the Ticket to login and + * access the Content Repository. * - * A valid ticket is needed in order to access the content from the - * repository. This method would be called evertime the tool needs to - * upload/download files from the content repository. + * A valid ticket is needed in order to access the content from the repository. This method would be called evertime + * the tool needs to upload/download files from the content repository. * * @return ITicket The ticket for repostory access * @throws SubmitFilesException @@ -759,8 +758,7 @@ } /** - * Export the XML fragment for the tool's content, along with any files - * needed for the content. + * Export the XML fragment for the tool's content, along with any files needed for the content. * * @throws DataMissingException * if no tool content matches the toolSessionId @@ -807,8 +805,7 @@ } /** - * Import the XML fragment for the tool's content, along with any files - * needed for the content. + * Import the XML fragment for the tool's content, along with any files needed for the content. * * @throws ToolException * if any other error occurs @@ -860,14 +857,12 @@ } /** - * Get the definitions for possible output for an activity, based on the - * toolContentId. These may be definitions that are always available for the - * tool (e.g. number of marks for Multiple Choice) or a custom definition - * created for a particular activity such as the answer to the third - * question contains the word Koala and hence the need for the toolContentId + * Get the definitions for possible output for an activity, based on the toolContentId. These may be definitions + * that are always available for the tool (e.g. number of marks for Multiple Choice) or a custom definition created + * for a particular activity such as the answer to the third question contains the word Koala and hence the need for + * the toolContentId * - * @return SortedMap of ToolOutputDefinitions with the key being the name of - * each definition + * @return SortedMap of ToolOutputDefinitions with the key being the name of each definition */ public SortedMap getToolOutputDefinitions(Long toolContentId) throws ToolException { Forum forum = getForumByContentId(toolContentId); @@ -878,8 +873,8 @@ } /** - * @see org.lamsfoundation.lams.tool.ToolSessionManager#createToolSession(java.lang.Long, - * java.lang.String, java.lang.Long) + * @see org.lamsfoundation.lams.tool.ToolSessionManager#createToolSession(java.lang.Long, java.lang.String, + * java.lang.Long) */ public void createToolSession(Long toolSessionId, String toolSessionName, Long toolContentId) throws ToolException { ForumToolSession session = new ForumToolSession(); @@ -947,8 +942,8 @@ /** * Get the tool output for the given tool output names. * - * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.util.List, - * java.lang.Long, java.lang.Long) + * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.util.List, java.lang.Long, + * java.lang.Long) */ public SortedMap getToolOutput(List names, Long toolSessionId, Long learnerId) { @@ -959,8 +954,8 @@ /** * Get the tool output for the given tool output name. * - * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.lang.String, - * java.lang.Long, java.lang.Long) + * @see org.lamsfoundation.lams.tool.ToolSessionManager#getToolOutput(java.lang.String, java.lang.Long, + * java.lang.Long) */ public ToolOutput getToolOutput(String name, Long toolSessionId, Long learnerId) { return forumOutputFactory.getToolOutput(name, this, toolSessionId, learnerId); @@ -1121,8 +1116,7 @@ } /** - * Set the description, throws away the title value as this is not supported - * in 2.0 + * Set the description, throws away the title value as this is not supported in 2.0 */ public void setReflectiveData(Long toolContentId, String title, String description) throws ToolException, DataMissingException { @@ -1139,13 +1133,14 @@ /** * Sends marks straight to gradebook from a forum report + * * @param user * @param toolSessionID */ @SuppressWarnings("unchecked") public void sendMarksToGradebook(ForumUser user, Long toolSessionID) { - List messages = (List) getMessagesByUserUid(user.getUid(), toolSessionID); + List messages = getMessagesByUserUid(user.getUid(), toolSessionID); if (messages != null) { Float totalMark = null; for (MessageDTO message : messages) { Index: lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/LearningAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/LearningAction.java,v diff -u -r1.65 -r1.65.6.1 --- lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/LearningAction.java 2 Feb 2009 03:21:24 -0000 1.65 +++ lams_tool_forum/src/java/org/lamsfoundation/lams/tool/forum/web/actions/LearningAction.java 25 May 2009 18:16:29 -0000 1.65.6.1 @@ -47,7 +47,6 @@ import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; -import org.hibernate.Session; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; @@ -64,7 +63,6 @@ import org.lamsfoundation.lams.tool.forum.persistence.Message; import org.lamsfoundation.lams.tool.forum.persistence.PersistenceException; import org.lamsfoundation.lams.tool.forum.persistence.Timestamp; -import org.lamsfoundation.lams.tool.forum.service.ForumService; import org.lamsfoundation.lams.tool.forum.service.ForumServiceProxy; import org.lamsfoundation.lams.tool.forum.service.IForumService; import org.lamsfoundation.lams.tool.forum.util.ForumConstants; @@ -82,955 +80,949 @@ * User: conradb Date: 24/06/2005 Time: 10:54:09 */ public class LearningAction extends Action { - 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 IForumService forumService; + private IForumService forumService; - @Override - public final ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { - String param = mapping.getParameter(); - // --------------Forum Level ------------------ - if (param.equals("viewForum")) { - return viewForum(mapping, form, request, response); - } - if (param.equals("finish")) { - return finish(mapping, form, request, response); - } + @Override + public final ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + String param = mapping.getParameter(); + // --------------Forum Level ------------------ + if (param.equals("viewForum")) { + return viewForum(mapping, form, request, response); + } + if (param.equals("finish")) { + return finish(mapping, form, request, response); + } - // --------------Topic Level ------------------ - if (param.equals("viewTopic")) { - return viewTopic(mapping, form, request, response); - } - if (param.equals("newTopic")) { - return newTopic(mapping, form, request, response); - } - if (param.equals("createTopic")) { - return createTopic(mapping, form, request, response); - } - if (param.equals("newReplyTopic")) { - return newReplyTopic(mapping, form, request, response); - } - if (param.equals("replyTopic")) { - return replyTopic(mapping, form, request, response); - } - if (param.equals("editTopic")) { - return editTopic(mapping, form, request, response); - } - if (param.equals("updateTopic")) { - return updateTopic(mapping, form, request, response); - } - if (param.equals("deleteAttachment")) { - return deleteAttachment(mapping, form, request, response); - } - if (param.equals("updateMessageHideFlag")) { - return updateMessageHideFlag(mapping, form, request, response); - } + // --------------Topic Level ------------------ + if (param.equals("viewTopic")) { + return viewTopic(mapping, form, request, response); + } + if (param.equals("newTopic")) { + return newTopic(mapping, form, request, response); + } + if (param.equals("createTopic")) { + return createTopic(mapping, form, request, response); + } + if (param.equals("newReplyTopic")) { + return newReplyTopic(mapping, form, request, response); + } + if (param.equals("replyTopic")) { + return replyTopic(mapping, form, request, response); + } + if (param.equals("editTopic")) { + return editTopic(mapping, form, request, response); + } + if (param.equals("updateTopic")) { + return updateTopic(mapping, form, request, response); + } + if (param.equals("deleteAttachment")) { + return deleteAttachment(mapping, form, request, response); + } + if (param.equals("updateMessageHideFlag")) { + return updateMessageHideFlag(mapping, form, request, response); + } - //================ Reflection ======================= - if (param.equals("newReflection")) { - return newReflection(mapping, form, request, response); - } - if (param.equals("submitReflection")) { - return submitReflection(mapping, form, request, response); - } - - return mapping.findForward("error"); + // ================ Reflection ======================= + if (param.equals("newReflection")) { + return newReflection(mapping, form, request, response); } + if (param.equals("submitReflection")) { + return submitReflection(mapping, form, request, response); + } - // ========================================================================================== - // Forum level methods - // ========================================================================================== - /** - * Display root topics of a forum. This page will be the initial page of - * Learner page. - * @throws Exception - * - */ - private ActionForward viewForum(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws Exception { + return mapping.findForward("error"); + } - //initial Session Map - String sessionMapID = request.getParameter(ForumConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap; - //refresh forum page, not initial enter - if (sessionMapID != null) { - sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - } - else { - sessionMap = new SessionMap(); - request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + // ========================================================================================== + // Forum level methods + // ========================================================================================== + /** + * Display root topics of a forum. This page will be the initial page of Learner page. + * + * @throws Exception + * + */ + private ActionForward viewForum(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { - } - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); + // initial Session Map + String sessionMapID = request.getParameter(ForumConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap; + // refresh forum page, not initial enter + if (sessionMapID != null) { + sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + } else { + sessionMap = new SessionMap(); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); - // set the mode into http session - ToolAccessMode mode = null; - try { - mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, LearningAction.MODE_OPTIONAL); - } - catch (Exception exp) { - } - if (mode == null) { - //set it as default mode - mode = ToolAccessMode.LEARNER; - } + } + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMap.getSessionID()); - // get sessionId from HttpServletRequest - Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + // set the mode into http session + ToolAccessMode mode = null; + try { + mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, LearningAction.MODE_OPTIONAL); + } catch (Exception exp) { + } + if (mode == null) { + // set it as default mode + mode = ToolAccessMode.LEARNER; + } - // Try to get ForumID according to sessionId - forumService = getForumManager(); - ForumToolSession session = forumService.getSessionBySessionId(sessionId); + // get sessionId from HttpServletRequest + Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); - if (session == null || session.getForum() == null) { - LearningAction.log.error("Failed on getting session by given sessionID:" + sessionId); - throw new Exception("Failed on getting session by given sessionID:" + sessionId); - } + // Try to get ForumID according to sessionId + forumService = getForumManager(); + ForumToolSession session = forumService.getSessionBySessionId(sessionId); - Forum forum = session.getForum(); - //lock on finish - ForumUser forumUser = getCurrentUser(request, sessionId); - boolean lock = forum.getLockWhenFinished() && forumUser.isSessionFinished(); + if (session == null || session.getForum() == null) { + LearningAction.log.error("Failed on getting session by given sessionID:" + sessionId); + throw new Exception("Failed on getting session by given sessionID:" + sessionId); + } - //set some option flag to HttpSession - // if allowRichEditor = true then don't restrict the number of chars - // if isLimitedInput = false then don't restrict the number of chars - // Indicate don't restrict number of chars by allowNumber = 0 - Long forumId = forum.getUid(); - Boolean allowRichEditor = new Boolean(forum.isAllowRichEditor()); - int allowNumber = forum.isLimitedInput() || forum.isAllowRichEditor() ? forum.getLimitedChar() : 0; + Forum forum = session.getForum(); + // lock on finish + ForumUser forumUser = getCurrentUser(request, sessionId); + boolean lock = forum.getLockWhenFinished() && forumUser.isSessionFinished(); - sessionMap.put(ForumConstants.FORUM_ID, forumId); - sessionMap.put(AttributeNames.ATTR_MODE, mode); - sessionMap.put(ForumConstants.ATTR_FINISHED_LOCK, new Boolean(lock)); - sessionMap.put(ForumConstants.ATTR_LOCK_WHEN_FINISHED, forum.getLockWhenFinished()); - sessionMap.put(ForumConstants.ATTR_USER_FINISHED, forumUser.isSessionFinished()); - sessionMap.put(ForumConstants.ATTR_ALLOW_EDIT, forum.isAllowEdit()); - sessionMap.put(ForumConstants.ATTR_ALLOW_UPLOAD, forum.isAllowUpload()); - sessionMap.put(ForumConstants.ATTR_ALLOW_NEW_TOPICS, forum.isAllowNewTopic()); - sessionMap.put(ForumConstants.ATTR_ALLOW_RICH_EDITOR, allowRichEditor); - sessionMap.put(ForumConstants.ATTR_LIMITED_CHARS, new Integer(allowNumber)); - sessionMap.put(AttributeNames.PARAM_TOOL_SESSION_ID, sessionId); - sessionMap.put(ForumConstants.ATTR_FORUM_TITLE, forum.getTitle()); - sessionMap.put(ForumConstants.ATTR_FORUM_INSTRCUTION, forum.getInstructions()); - sessionMap.put(ForumConstants.ATTR_MINIMUM_REPLY, forum.getMinimumReply()); - sessionMap.put(ForumConstants.ATTR_MAXIMUM_REPLY, forum.getMaximumReply()); + // set some option flag to HttpSession + // if allowRichEditor = true then don't restrict the number of chars + // if isLimitedInput = false then don't restrict the number of chars + // Indicate don't restrict number of chars by allowNumber = 0 + Long forumId = forum.getUid(); + Boolean allowRichEditor = new Boolean(forum.isAllowRichEditor()); + int allowNumber = forum.isLimitedInput() || forum.isAllowRichEditor() ? forum.getLimitedChar() : 0; - // Should we show the reflection or not? We shouldn't show it when the screen is accessed - // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. - // Need to constantly past this value on, rather than hiding just the once, as the View Forum - // screen has a refresh button. - boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); - sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); + sessionMap.put(ForumConstants.FORUM_ID, forumId); + sessionMap.put(AttributeNames.ATTR_MODE, mode); + sessionMap.put(ForumConstants.ATTR_FINISHED_LOCK, new Boolean(lock)); + sessionMap.put(ForumConstants.ATTR_LOCK_WHEN_FINISHED, forum.getLockWhenFinished()); + sessionMap.put(ForumConstants.ATTR_USER_FINISHED, forumUser.isSessionFinished()); + sessionMap.put(ForumConstants.ATTR_ALLOW_EDIT, forum.isAllowEdit()); + sessionMap.put(ForumConstants.ATTR_ALLOW_UPLOAD, forum.isAllowUpload()); + sessionMap.put(ForumConstants.ATTR_ALLOW_NEW_TOPICS, forum.isAllowNewTopic()); + sessionMap.put(ForumConstants.ATTR_ALLOW_RICH_EDITOR, allowRichEditor); + sessionMap.put(ForumConstants.ATTR_LIMITED_CHARS, new Integer(allowNumber)); + sessionMap.put(AttributeNames.PARAM_TOOL_SESSION_ID, sessionId); + sessionMap.put(ForumConstants.ATTR_FORUM_TITLE, forum.getTitle()); + sessionMap.put(ForumConstants.ATTR_FORUM_INSTRCUTION, forum.getInstructions()); + sessionMap.put(ForumConstants.ATTR_MINIMUM_REPLY, forum.getMinimumReply()); + sessionMap.put(ForumConstants.ATTR_MAXIMUM_REPLY, forum.getMaximumReply()); - if (hideReflection) { - sessionMap.put(ForumConstants.ATTR_REFLECTION_ON, false); - sessionMap.put(ForumConstants.ATTR_REFLECTION_INSTRUCTION, ""); - sessionMap.put(ForumConstants.ATTR_REFLECTION_ENTRY, ""); - } - else { - sessionMap.put(ForumConstants.ATTR_REFLECTION_ON, forum.isReflectOnActivity()); - sessionMap.put(ForumConstants.ATTR_REFLECTION_INSTRUCTION, forum.getReflectInstructions()); + // Should we show the reflection or not? We shouldn't show it when the screen is accessed + // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. + // Need to constantly past this value on, rather than hiding just the once, as the View Forum + // screen has a refresh button. + boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); + sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); - NotebookEntry notebookEntry = forumService.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, - ForumConstants.TOOL_SIGNATURE, forumUser.getUserId().intValue()); - sessionMap.put(ForumConstants.ATTR_REFLECTION_ENTRY, notebookEntry != null ? notebookEntry.getEntry() : ""); - } + if (hideReflection) { + sessionMap.put(ForumConstants.ATTR_REFLECTION_ON, false); + sessionMap.put(ForumConstants.ATTR_REFLECTION_INSTRUCTION, ""); + sessionMap.put(ForumConstants.ATTR_REFLECTION_ENTRY, ""); + } else { + sessionMap.put(ForumConstants.ATTR_REFLECTION_ON, forum.isReflectOnActivity()); + sessionMap.put(ForumConstants.ATTR_REFLECTION_INSTRUCTION, forum.getReflectInstructions()); - //add define later support - if (forum.isDefineLater()) { - return mapping.findForward("defineLater"); - } + NotebookEntry notebookEntry = forumService.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + ForumConstants.TOOL_SIGNATURE, forumUser.getUserId().intValue()); + sessionMap.put(ForumConstants.ATTR_REFLECTION_ENTRY, notebookEntry != null ? notebookEntry.getEntry() : ""); + } - //set contentInUse flag to true! - forum.setContentInUse(true); - forum.setDefineLater(false); - forumService.updateForum(forum); + // add define later support + if (forum.isDefineLater()) { + return mapping.findForward("defineLater"); + } - //add run offline support - if (forum.getRunOffline()) { - return mapping.findForward("runOffline"); - } + // set contentInUse flag to true! + forum.setContentInUse(true); + forum.setDefineLater(false); + forumService.updateForum(forum); - // get all root topic to display on init page - List rootTopics = forumService.getRootTopics(sessionId); - if (!forum.isAllowNewTopic()) { - // add the number post the learner has made for each topic. - updateNumOfPosts(rootTopics, forumUser); - } - request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); + // add run offline support + if (forum.getRunOffline()) { + return mapping.findForward("runOffline"); + } - if (forum.isNotifyLearnersOnMarkRelease()) { - forumService.getEventNotificationService().createEvent(ForumConstants.TOOL_SIGNATURE, - ForumConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, forum.getContentId(), - forumService.getLocalisedMessage("event.mark.release.subject", null), - forumService.getLocalisedMessage("event.mark.release.body", null)); + // get all root topic to display on init page + List rootTopics = forumService.getRootTopics(sessionId); + if (!forum.isAllowNewTopic()) { + // add the number post the learner has made for each topic. + updateNumOfPosts(rootTopics, forumUser); + } + request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); - forumService.getEventNotificationService().subscribe(ForumConstants.TOOL_SIGNATURE, - ForumConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, forum.getContentId(), - forumUser.getUserId().longValue(), IEventNotificationService.DELIVERY_METHOD_MAIL, - IEventNotificationService.PERIODICITY_SINGLE); - } - - // displaying new postings - for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { - MessageDTO messageDTO = (MessageDTO) iterator.next(); - int numOfNewPosts = forumService.getNewMessagesNum( - messageDTO.getMessage().getUid(), forumUser.getUid()); - if (numOfNewPosts == -1) // first time; show all postings as new, including root message - messageDTO.setNewPostingsNum(messageDTO.getMessage().getReplyNumber() + 1); - else - messageDTO.setNewPostingsNum(numOfNewPosts); - - messageDTO.setLastTopicDate(forumService.getLastTopicDate(messageDTO.getMessage().getUid())); - } + if (forum.isNotifyLearnersOnMarkRelease()) { + forumService.getEventNotificationService().createEvent(ForumConstants.TOOL_SIGNATURE, + ForumConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, forum.getContentId(), + forumService.getLocalisedMessage("event.mark.release.subject", null), + forumService.getLocalisedMessage("event.mark.release.body", null)); - return mapping.findForward("success"); + forumService.getEventNotificationService().subscribe(ForumConstants.TOOL_SIGNATURE, + ForumConstants.EVENT_NAME_NOTIFY_LEARNERS_ON_MARK_RELEASE, forum.getContentId(), + forumUser.getUserId().longValue(), IEventNotificationService.DELIVERY_METHOD_MAIL, + IEventNotificationService.PERIODICITY_SINGLE); } - private void updateNumOfPosts(List rootTopics, ForumUser forumUser) { - for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { - MessageDTO messageDTO = (MessageDTO) iterator.next(); - int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), messageDTO.getMessage().getUid()); - messageDTO.setNumOfPosts(numOfPosts); - } + // displaying new postings + for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { + MessageDTO messageDTO = (MessageDTO) iterator.next(); + int numOfNewPosts = forumService.getNewMessagesNum(messageDTO.getMessage().getUid(), forumUser.getUid()); + if (numOfNewPosts == -1) { + messageDTO.setNewPostingsNum(messageDTO.getMessage().getReplyNumber() + 1); + } else { + messageDTO.setNewPostingsNum(numOfNewPosts); + } + + messageDTO.setLastTopicDate(forumService.getLastTopicDate(messageDTO.getMessage().getUid())); } - /** - * Learner click "finish" button in forum page, this method will turn on - * session status flag for this learner. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward finish(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + return mapping.findForward("success"); + } - ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); - Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + private void updateNumOfPosts(List rootTopics, ForumUser forumUser) { + for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { + MessageDTO messageDTO = (MessageDTO) iterator.next(); + int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), messageDTO.getMessage().getUid()); + messageDTO.setNumOfPosts(numOfPosts); + } + } - forumService = getForumManager(); + /** + * Learner click "finish" button in forum page, this method will turn on session status flag for this learner. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward finish(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - if (mode == ToolAccessMode.LEARNER || mode == ToolAccessMode.AUTHOR) { - if (!validateBeforeFinish(request, sessionMapID)) { - return mapping.getInputForward(); - } + ToolAccessMode mode = (ToolAccessMode) sessionMap.get(AttributeNames.ATTR_MODE); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - String nextActivityUrl; - try { - // get session from shared session. - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - Long userID = new Long(user.getUserID().longValue()); + forumService = getForumManager(); - //finish current session for user - forumService.finishUserSession(getCurrentUser(request, sessionId)); - ToolSessionManager sessionMgrService = ForumServiceProxy.getToolSessionManager(getServlet().getServletContext()); - nextActivityUrl = sessionMgrService.leaveToolSession(sessionId, userID); - response.sendRedirect(nextActivityUrl); - } - catch (DataMissingException e) { - throw new ForumException(e); - } - catch (ToolException e) { - throw new ForumException(e); - } - catch (IOException e) { - throw new ForumException(e); - } - return null; + if (mode == ToolAccessMode.LEARNER || mode == ToolAccessMode.AUTHOR) { + if (!validateBeforeFinish(request, sessionMapID)) { + return mapping.getInputForward(); + } - } - // get all root topic to display on init page - List rootTopics = forumService.getRootTopics(sessionId); - request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); + String nextActivityUrl; + try { + // get session from shared session. + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); - return mapping.getInputForward(); + // finish current session for user + forumService.finishUserSession(getCurrentUser(request, sessionId)); + ToolSessionManager sessionMgrService = ForumServiceProxy.getToolSessionManager(getServlet() + .getServletContext()); + nextActivityUrl = sessionMgrService.leaveToolSession(sessionId, userID); + response.sendRedirect(nextActivityUrl); + } catch (DataMissingException e) { + throw new ForumException(e); + } catch (ToolException e) { + throw new ForumException(e); + } catch (IOException e) { + throw new ForumException(e); + } + return null; + } + // get all root topic to display on init page + List rootTopics = forumService.getRootTopics(sessionId); + request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); - /** - * Submit reflection form input database. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { - ReflectionForm refForm = (ReflectionForm) form; - Integer userId = refForm.getUserID(); + return mapping.getInputForward(); + } - String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + /** + * Submit reflection form input database. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward submitReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + ReflectionForm refForm = (ReflectionForm) form; + Integer userId = refForm.getUserID(); - // check for existing notebook entry - NotebookEntry entry = forumService.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, - ForumConstants.TOOL_SIGNATURE, userId); + String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - if (entry == null) { - // create new entry - forumService.createNotebookEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, ForumConstants.TOOL_SIGNATURE, - userId, refForm.getEntryText()); - } - else { - // update existing entry - entry.setEntry(refForm.getEntryText()); - entry.setLastModified(new Date()); - forumService.updateEntry(entry); - } + // check for existing notebook entry + NotebookEntry entry = forumService.getEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + ForumConstants.TOOL_SIGNATURE, userId); - return finish(mapping, form, request, response); + if (entry == null) { + // create new entry + forumService.createNotebookEntry(sessionId, CoreNotebookConstants.NOTEBOOK_TOOL, + ForumConstants.TOOL_SIGNATURE, userId, refForm.getEntryText()); + } else { + // update existing entry + entry.setEntry(refForm.getEntryText()); + entry.setLastModified(new Date()); + forumService.updateEntry(entry); } - /** - * Display empty reflection form. - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward newReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + return finish(mapping, form, request, response); + } - //get session value - String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); - if (!validateBeforeFinish(request, sessionMapID)) { - return mapping.getInputForward(); - } + /** + * Display empty reflection form. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward newReflection(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - ReflectionForm refForm = (ReflectionForm) form; - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + // get session value + String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); + if (!validateBeforeFinish(request, sessionMapID)) { + return mapping.getInputForward(); + } - refForm.setUserID(user.getUserID()); - refForm.setSessionMapID(sessionMapID); + ReflectionForm refForm = (ReflectionForm) form; + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - // get the existing reflection entry - IForumService submitFilesService = getForumManager(); + refForm.setUserID(user.getUserID()); + refForm.setSessionMapID(sessionMapID); - SessionMap map = (SessionMap) request.getSession().getAttribute(sessionMapID); - Long toolSessionID = (Long) map.get(AttributeNames.PARAM_TOOL_SESSION_ID); - NotebookEntry entry = submitFilesService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, - ForumConstants.TOOL_SIGNATURE, user.getUserID()); + // get the existing reflection entry + IForumService submitFilesService = getForumManager(); - if (entry != null) { - refForm.setEntryText(entry.getEntry()); - } + SessionMap map = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long toolSessionID = (Long) map.get(AttributeNames.PARAM_TOOL_SESSION_ID); + NotebookEntry entry = submitFilesService.getEntry(toolSessionID, CoreNotebookConstants.NOTEBOOK_TOOL, + ForumConstants.TOOL_SIGNATURE, user.getUserID()); - return mapping.findForward("success"); + if (entry != null) { + refForm.setEntryText(entry.getEntry()); } - // ========================================================================================== - // Topic level methods - // ========================================================================================== + return mapping.findForward("success"); + } - /** - * Display read-only page for a special topic. Topic will arrange by Tree - * structure. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward viewTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + // ========================================================================================== + // Topic level methods + // ========================================================================================== - forumService = getForumManager(); + /** + * Display read-only page for a special topic. Topic will arrange by Tree structure. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward viewTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - Long rootTopicId = WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID); + forumService = getForumManager(); - String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - sessionMap.put(ForumConstants.ATTR_ROOT_TOPIC_UID, rootTopicId); + Long rootTopicId = WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID); - // get forum user and forum - ForumUser forumUser = getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID)); - Forum forum = forumUser.getSession().getForum(); + String sessionMapID = WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + sessionMap.put(ForumConstants.ATTR_ROOT_TOPIC_UID, rootTopicId); - // get root topic list - List msgDtoList = forumService.getTopicThread(rootTopicId); - updateMesssageFlag(msgDtoList); - request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); + // get forum user and forum + ForumUser forumUser = getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID)); + Forum forum = forumUser.getSession().getForum(); - // check if we can still make posts in this topic - int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), msgDtoList.get(0).getMessage().getUid()); - boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() && !forum.isAllowNewTopic() ? Boolean.TRUE - : Boolean.FALSE; - request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); - request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); + // get root topic list + List msgDtoList = forumService.getTopicThread(rootTopicId); + updateMesssageFlag(msgDtoList); + request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); - //transfer SessionMapID as well - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMapID); + // check if we can still make posts in this topic + int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), msgDtoList.get(0).getMessage() + .getUid()); + boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() + && !forum.isAllowNewTopic() ? Boolean.TRUE : Boolean.FALSE; + request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); + request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); - // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed - // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. - // Need to constantly past this value on, rather than hiding just the once, as the View Forum - // screen has a refresh button. Need to pass it through the view topic screen and dependent screens - // as it has a link from the view topic screen back to View Forum screen. - boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); - sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); - - // Saving or updating user timestamp - saveUserTimestamp(rootTopicId, forumUser); - - return mapping.findForward("success"); + // transfer SessionMapID as well + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMapID); + + // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed + // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. + // Need to constantly past this value on, rather than hiding just the once, as the View Forum + // screen has a refresh button. Need to pass it through the view topic screen and dependent screens + // as it has a link from the view topic screen back to View Forum screen. + boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); + sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); + + // Saving or updating user timestamp + saveUserTimestamp(rootTopicId, forumUser); + + return mapping.findForward("success"); + } + + /** + * Saving user timestamp + * + * @param toorTopicId + * @param forumUser + * @return + */ + private void saveUserTimestamp(Long rootTopicId, ForumUser forumUser) { + Date curDate = new Date(); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + curDate = dateFormat.parse(dateFormat.format(new Date())); + } catch (ParseException pe) { + pe.printStackTrace(); } - - /** - * Saving user timestamp - * - * @param toorTopicId - * @param forumUser - * @return - */ - private void saveUserTimestamp(Long rootTopicId, ForumUser forumUser) - { - Date curDate = new Date(); - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - try { - curDate = dateFormat.parse(dateFormat.format(new Date())); - } catch(ParseException pe) { - pe.printStackTrace(); - } - - Timestamp timestamp = forumService.getTimestamp(rootTopicId, forumUser.getUid()); - if (timestamp != null) - { - timestamp.setTimestamp(curDate); - forumService.saveTimestamp(timestamp); - } - else - { - timestamp = new Timestamp(); - timestamp.setMessage(forumService.getMessage(rootTopicId)); - timestamp.setTimestamp(curDate); - timestamp.setForumUser(forumUser); - forumService.saveTimestamp(timestamp); - } + + Timestamp timestamp = forumService.getTimestamp(rootTopicId, forumUser.getUid()); + if (timestamp != null) { + timestamp.setTimestamp(curDate); + forumService.saveTimestamp(timestamp); + } else { + timestamp = new Timestamp(); + timestamp.setMessage(forumService.getMessage(rootTopicId)); + timestamp.setTimestamp(curDate); + timestamp.setForumUser(forumUser); + forumService.saveTimestamp(timestamp); } + } - /** - * Display empty page for a new topic in forum - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward newTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { - //transfer SessionMapID as well - ((MessageForm) form).setSessionMapID(WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID)); + /** + * Display empty page for a new topic in forum + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward newTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + // transfer SessionMapID as well + ((MessageForm) form).setSessionMapID(WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID)); - return mapping.findForward("success"); - } + return mapping.findForward("success"); + } - /** - * Create a new root topic. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - * @throws PersistenceException - */ - public ActionForward createTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, PersistenceException { + /** + * Create a new root topic. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + * @throws PersistenceException + */ + public ActionForward createTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException, PersistenceException { - MessageForm messageForm = (MessageForm) form; - SessionMap sessionMap = getSessionMap(request, messageForm); - Long forumId = (Long) sessionMap.get(ForumConstants.FORUM_ID); - Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + MessageForm messageForm = (MessageForm) form; + SessionMap sessionMap = getSessionMap(request, messageForm); + Long forumId = (Long) sessionMap.get(ForumConstants.FORUM_ID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - Message message = messageForm.getMessage(); - message.setIsAuthored(false); - message.setCreated(new Date()); - message.setUpdated(new Date()); - message.setLastReplyDate(new Date()); - ForumUser forumUser = getCurrentUser(request, sessionId); - message.setCreatedBy(forumUser); - message.setModifiedBy(forumUser); - setAttachment(messageForm, message); + Message message = messageForm.getMessage(); + message.setIsAuthored(false); + message.setCreated(new Date()); + message.setUpdated(new Date()); + message.setLastReplyDate(new Date()); + ForumUser forumUser = getCurrentUser(request, sessionId); + message.setCreatedBy(forumUser); + message.setModifiedBy(forumUser); + setAttachment(messageForm, message); - // save message into database - forumService = getForumManager(); - forumService.createRootTopic(forumId, sessionId, message); + // save message into database + forumService = getForumManager(); + forumService.createRootTopic(forumId, sessionId, message); - // echo back current root topic to forum init page - List rootTopics = forumService.getRootTopics(sessionId); - request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); - - saveUserTimestamp(message.getUid(), forumUser); - - for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { - MessageDTO messageDTO = (MessageDTO) iterator.next(); - int numOfNewPosts = forumService.getNewMessagesNum( - messageDTO.getMessage().getUid(), forumUser.getUid()); - if (numOfNewPosts == -1) // first time; show all postings as new, including root message - messageDTO.setNewPostingsNum(messageDTO.getMessage().getReplyNumber() + 1); - else - messageDTO.setNewPostingsNum(numOfNewPosts); - - messageDTO.setLastTopicDate(forumService.getLastTopicDate(messageDTO.getMessage().getUid())); - } - - return mapping.findForward("success"); - } + // echo back current root topic to forum init page + List rootTopics = forumService.getRootTopics(sessionId); + request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); - /** - * Display replay topic page. Message form subject will include parent - * topics same subject. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward newReplyTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { - String sessionMapID = request.getParameter(ForumConstants.ATTR_SESSION_MAP_ID); + saveUserTimestamp(message.getUid(), forumUser); - MessageForm msgForm = (MessageForm) form; - msgForm.setSessionMapID(sessionMapID); + for (Iterator iterator = rootTopics.iterator(); iterator.hasNext();) { + MessageDTO messageDTO = (MessageDTO) iterator.next(); + int numOfNewPosts = forumService.getNewMessagesNum(messageDTO.getMessage().getUid(), forumUser.getUid()); + if (numOfNewPosts == -1) { + messageDTO.setNewPostingsNum(messageDTO.getMessage().getReplyNumber() + 1); + } else { + messageDTO.setNewPostingsNum(numOfNewPosts); + } - Long parentId = WebUtil.readLongParam(request, ForumConstants.ATTR_PARENT_TOPIC_ID); - // get parent topic, it can decide default subject of reply. - MessageDTO topic = getTopic(parentId); + messageDTO.setLastTopicDate(forumService.getLastTopicDate(messageDTO.getMessage().getUid())); + } - if (topic != null && topic.getMessage() != null) { - String reTitle = topic.getMessage().getSubject(); + return mapping.findForward("success"); + } - MessageDTO originalMessage = MessageDTO.getMessageDTO(topic.getMessage()); + /** + * Display replay topic page. Message form subject will include parent topics same subject. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward newReplyTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String sessionMapID = request.getParameter(ForumConstants.ATTR_SESSION_MAP_ID); - request.setAttribute(ForumConstants.ATTR_ORIGINAL_MESSAGE, originalMessage); + MessageForm msgForm = (MessageForm) form; + msgForm.setSessionMapID(sessionMapID); - // echo back current topic subject to web page - if (reTitle != null && !reTitle.trim().startsWith("Re:")) { - msgForm.getMessage().setSubject("Re:" + reTitle); - } - else { - msgForm.getMessage().setSubject(reTitle); - } - } - SessionMap sessionMap = getSessionMap(request, msgForm); - sessionMap.put(ForumConstants.ATTR_PARENT_TOPIC_ID, parentId); + Long parentId = WebUtil.readLongParam(request, ForumConstants.ATTR_PARENT_TOPIC_ID); + // get parent topic, it can decide default subject of reply. + MessageDTO topic = getTopic(parentId); - // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed - // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. - // Need to constantly past this value on, rather than hiding just the once, as the View Forum - // screen has a refresh button. Need to pass it through the view topic screen and dependent screens - // as it has a link from the view topic screen back to View Forum screen. - boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); - sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); + if (topic != null && topic.getMessage() != null) { + String reTitle = topic.getMessage().getSubject(); - return mapping.findForward("success"); - } + MessageDTO originalMessage = MessageDTO.getMessageDTO(topic.getMessage()); - /** - * Create a replayed topic for a parent topic. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward replyTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + request.setAttribute(ForumConstants.ATTR_ORIGINAL_MESSAGE, originalMessage); - MessageForm messageForm = (MessageForm) form; - SessionMap sessionMap = getSessionMap(request, messageForm); - Long parentId = (Long) sessionMap.get(ForumConstants.ATTR_PARENT_TOPIC_ID); - Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + // echo back current topic subject to web page + if (reTitle != null && !reTitle.trim().startsWith("Re:")) { + msgForm.getMessage().setSubject("Re:" + reTitle); + } else { + msgForm.getMessage().setSubject(reTitle); + } + } + SessionMap sessionMap = getSessionMap(request, msgForm); + sessionMap.put(ForumConstants.ATTR_PARENT_TOPIC_ID, parentId); - Message message = messageForm.getMessage(); - message.setIsAuthored(false); - message.setCreated(new Date()); - message.setUpdated(new Date()); - message.setLastReplyDate(new Date()); - ForumUser forumUser = getCurrentUser(request, sessionId); - message.setCreatedBy(forumUser); - message.setModifiedBy(forumUser); - setAttachment(messageForm, message); + // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed + // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. + // Need to constantly past this value on, rather than hiding just the once, as the View Forum + // screen has a refresh button. Need to pass it through the view topic screen and dependent screens + // as it has a link from the view topic screen back to View Forum screen. + boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); + sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); - // save message into database - forumService = getForumManager(); - forumService.replyTopic(parentId, sessionId, message); + return mapping.findForward("success"); + } - // echo back this topic thread into page - Long rootTopicId = forumService.getRootTopicId(parentId); - List msgDtoList = forumService.getTopicThread(rootTopicId); - updateMesssageFlag(msgDtoList); + /** + * Create a replayed topic for a parent topic. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws InterruptedException + */ + private ActionForward replyTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws InterruptedException { - request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); + MessageForm messageForm = (MessageForm) form; + SessionMap sessionMap = getSessionMap(request, messageForm); + Long parentId = (Long) sessionMap.get(ForumConstants.ATTR_PARENT_TOPIC_ID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); - //check whether allow more posts for this user - ForumToolSession session = forumService.getSessionBySessionId(sessionId); - Forum forum = session.getForum(); - int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), ((MessageDTO) msgDtoList.get(0)).getMessage() - .getUid()); - boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() && !forum.isAllowNewTopic() ? Boolean.TRUE - : Boolean.FALSE; - request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); - request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); + Message message = messageForm.getMessage(); + message.setIsAuthored(false); + message.setCreated(new Date()); + message.setUpdated(new Date()); + message.setLastReplyDate(new Date()); + ForumUser forumUser = getCurrentUser(request, sessionId); + message.setCreatedBy(forumUser); + message.setModifiedBy(forumUser); + setAttachment(messageForm, message); - sessionMap.remove(ForumConstants.ATTR_ORIGINAL_MESSAGE); - - // Saving or updating user timestamp - saveUserTimestamp(rootTopicId, forumUser); + // save message into database + forumService = getForumManager(); - return mapping.findForward("success"); + // synchronized because of deadlock exceptions + synchronized (parentId) { + forumService.replyTopic(parentId, sessionId, message); } - /** - * Display a editable form for a special topic in order to update it. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws PersistenceException - */ - public ActionForward editTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws PersistenceException { - Long topicId = WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID); + // echo back this topic thread into page + Long rootTopicId = forumService.getRootTopicId(parentId); + List msgDtoList = forumService.getTopicThread(rootTopicId); + updateMesssageFlag(msgDtoList); - MessageDTO topic = getTopic(topicId); + request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); - // echo current topic content to web page - MessageForm msgForm = (MessageForm) form; - if (topic != null) { - msgForm.setMessage(topic.getMessage()); - request.setAttribute(ForumConstants.AUTHORING_TOPIC, topic); - } + // check whether allow more posts for this user + ForumToolSession session = forumService.getSessionBySessionId(sessionId); + Forum forum = session.getForum(); + int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), ((MessageDTO) msgDtoList.get(0)) + .getMessage().getUid()); + boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() + && !forum.isAllowNewTopic() ? Boolean.TRUE : Boolean.FALSE; + request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); + request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); - //cache this topicID, using in Update topic - SessionMap sessionMap = getSessionMap(request, msgForm); - sessionMap.put(ForumConstants.ATTR_TOPIC_ID, topicId); + sessionMap.remove(ForumConstants.ATTR_ORIGINAL_MESSAGE); - // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed - // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. - // Need to constantly past this value on, rather than hiding just the once, as the View Forum - // screen has a refresh button. Need to pass it through the view topic screen and dependent screens - // as it has a link from the view topic screen back to View Forum screen. - boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); - sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); + // Saving or updating user timestamp + saveUserTimestamp(rootTopicId, forumUser); - return mapping.findForward("success"); - } + return mapping.findForward("success"); + } - /** - * Delete attachment from topic. This method only reset attachment information in memory. The finally update - * will happen in updateTopic method. So topic can keep this attachment if user choose "Cancel" edit - * topic. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward deleteAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + /** + * Display a editable form for a special topic in order to update it. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws PersistenceException + */ + public ActionForward editTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws PersistenceException { + Long topicId = WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID); - //only reset not attachment flag. - MessageDTO dto = new MessageDTO(); - dto.setHasAttachment(false); - request.setAttribute(ForumConstants.AUTHORING_TOPIC, dto); - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute( - WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID)); - request.setAttribute(ForumConstants.ATTR_ALLOW_UPLOAD, sessionMap.get(ForumConstants.ATTR_ALLOW_UPLOAD)); + MessageDTO topic = getTopic(topicId); - return mapping.findForward("success"); + // echo current topic content to web page + MessageForm msgForm = (MessageForm) form; + if (topic != null) { + msgForm.setMessage(topic.getMessage()); + request.setAttribute(ForumConstants.AUTHORING_TOPIC, topic); } - /** - * Update a topic. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws PersistenceException - */ - public ActionForward updateTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws PersistenceException { + // cache this topicID, using in Update topic + SessionMap sessionMap = getSessionMap(request, msgForm); + sessionMap.put(ForumConstants.ATTR_TOPIC_ID, topicId); - forumService = getForumManager(); + // Should we show the reflection or not? We shouldn't show it when the View Forum screen is accessed + // from the Monitoring Summary screen, but we should when accessed from the Learner Progress screen. + // Need to constantly past this value on, rather than hiding just the once, as the View Forum + // screen has a refresh button. Need to pass it through the view topic screen and dependent screens + // as it has a link from the view topic screen back to View Forum screen. + boolean hideReflection = WebUtil.readBooleanParam(request, ForumConstants.ATTR_HIDE_REFLECTION, false); + sessionMap.put(ForumConstants.ATTR_HIDE_REFLECTION, hideReflection); - MessageForm messageForm = (MessageForm) form; - SessionMap sessionMap = getSessionMap(request, messageForm); - Long topicId = (Long) sessionMap.get(ForumConstants.ATTR_TOPIC_ID); - Message message = messageForm.getMessage(); + return mapping.findForward("success"); + } - boolean makeAuditEntry = ToolAccessMode.TEACHER.equals(sessionMap.get(AttributeNames.ATTR_MODE)); - String oldMessageString = null; + /** + * Delete attachment from topic. This method only reset attachment information in memory. The finally update will + * happen in updateTopic method. So topic can keep this attachment if user choose "Cancel" edit + * topic. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward deleteAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - // get PO from database and sync with Form - Message messagePO = forumService.getMessage(topicId); - if (makeAuditEntry) { - oldMessageString = messagePO.toString(); - } - messagePO.setSubject(message.getSubject()); - messagePO.setBody(message.getBody()); - messagePO.setUpdated(new Date()); - messagePO.setModifiedBy(getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID))); - setAttachment(messageForm, messagePO); + // only reset not attachment flag. + MessageDTO dto = new MessageDTO(); + dto.setHasAttachment(false); + request.setAttribute(ForumConstants.AUTHORING_TOPIC, dto); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute( + WebUtil.readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID)); + request.setAttribute(ForumConstants.ATTR_ALLOW_UPLOAD, sessionMap.get(ForumConstants.ATTR_ALLOW_UPLOAD)); - if (makeAuditEntry) { - Long userId = 0L; - String loginName = "Default"; - if (message.getCreatedBy() != null) { - userId = message.getCreatedBy().getUserId(); - loginName = message.getCreatedBy().getLoginName(); - } - forumService.getAuditService().logChange(ForumConstants.TOOL_SIGNATURE, userId, loginName, oldMessageString, - messagePO.toString()); - } + return mapping.findForward("success"); + } - // save message into database - // if we are in monitoring then we are probably editing some else's entry so log the change. - forumService.updateTopic(messagePO); + /** + * Update a topic. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws PersistenceException + */ + public ActionForward updateTopic(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws PersistenceException { - // echo back this topic thread into page - Long rootTopicId = forumService.getRootTopicId(topicId); - List msgDtoList = forumService.getTopicThread(rootTopicId); - updateMesssageFlag(msgDtoList); + forumService = getForumManager(); - // check if we can still make posts in this topic - ForumUser forumUser = getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID)); - Forum forum = forumUser.getSession().getForum(); - int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), ((MessageDTO) msgDtoList.get(0)).getMessage() - .getUid()); - boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() && !forum.isAllowNewTopic() ? Boolean.TRUE - : Boolean.FALSE; - request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); - request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); + MessageForm messageForm = (MessageForm) form; + SessionMap sessionMap = getSessionMap(request, messageForm); + Long topicId = (Long) sessionMap.get(ForumConstants.ATTR_TOPIC_ID); + Message message = messageForm.getMessage(); - request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); - - // Saving or updating user timestamp - saveUserTimestamp(rootTopicId, forumUser); - - return mapping.findForward("success"); + boolean makeAuditEntry = ToolAccessMode.TEACHER.equals(sessionMap.get(AttributeNames.ATTR_MODE)); + String oldMessageString = null; + + // get PO from database and sync with Form + Message messagePO = forumService.getMessage(topicId); + if (makeAuditEntry) { + oldMessageString = messagePO.toString(); } + messagePO.setSubject(message.getSubject()); + messagePO.setBody(message.getBody()); + messagePO.setUpdated(new Date()); + messagePO.setModifiedBy(getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID))); + setAttachment(messageForm, messagePO); - /** - * Sets the visibility of a message by updating the hide flag for a message - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - public ActionForward updateMessageHideFlag(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) { + if (makeAuditEntry) { + Long userId = 0L; + String loginName = "Default"; + if (message.getCreatedBy() != null) { + userId = message.getCreatedBy().getUserId(); + loginName = message.getCreatedBy().getLoginName(); + } + forumService.getAuditService().logChange(ForumConstants.TOOL_SIGNATURE, userId, loginName, + oldMessageString, messagePO.toString()); + } - Long msgId = new Long(WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID)); - Boolean hideFlag = new Boolean(WebUtil.readBooleanParam(request, "hideFlag")); - forumService = getForumManager(); + // save message into database + // if we are in monitoring then we are probably editing some else's entry so log the change. + forumService.updateTopic(messagePO); - // TODO Skipping permissions for now, currently having issues with default learning designs not having an create_by field - // Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); - // check if the user has permission to hide posts. - // ForumToolSession toolSession = forumService - // .getSessionBySessionId(sessionId); - // - // Forum forum = toolSession.getForum(); - // ForumUser currentUser = getCurrentUser(request,sessionId); - // ForumUser forumCreatedBy = forum.getCreatedBy(); + // echo back this topic thread into page + Long rootTopicId = forumService.getRootTopicId(topicId); + List msgDtoList = forumService.getTopicThread(rootTopicId); + updateMesssageFlag(msgDtoList); - // we should be looking at whether a user is a teacher and more specifically staff - // if (currentUser.getUserId().equals(forumCreatedBy.getUserId())) { - forumService.updateMessageHideFlag(msgId, hideFlag.booleanValue()); - // } else { - // log.info(currentUser + "does not have permission to hide/show postings in forum: " + forum.getUid()); - // log.info("Forum created by :" + forumCreatedBy.getUid() + ", Current User is: " + currentUser.getUid()); - // } + // check if we can still make posts in this topic + ForumUser forumUser = getCurrentUser(request, (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID)); + Forum forum = forumUser.getSession().getForum(); + int numOfPosts = forumService.getNumOfPostsByTopic(forumUser.getUserId(), ((MessageDTO) msgDtoList.get(0)) + .getMessage().getUid()); + boolean noMorePosts = forum.getMaximumReply() != 0 && numOfPosts >= forum.getMaximumReply() + && !forum.isAllowNewTopic() ? Boolean.TRUE : Boolean.FALSE; + request.setAttribute(ForumConstants.ATTR_NO_MORE_POSTS, noMorePosts); + request.setAttribute(ForumConstants.ATTR_NUM_OF_POSTS, numOfPosts); - // echo back this topic thread into page - Long rootTopicId = forumService.getRootTopicId(msgId); - List msgDtoList = forumService.getTopicThread(rootTopicId); - updateMesssageFlag(msgDtoList); - request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, WebUtil - .readStrParam(request, ForumConstants.ATTR_SESSION_MAP_ID)); - - return mapping.findForward("success"); - } + request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, messageForm.getSessionMapID()); - // ========================================================================================== - // Utility methods - // ========================================================================================== - /** - * Validation method to check whether user posts meet minimum number. - */ - private boolean validateBeforeFinish(HttpServletRequest request, String sessionMapID) { - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); - Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + // Saving or updating user timestamp + saveUserTimestamp(rootTopicId, forumUser); - ForumToolSession session = forumService.getSessionBySessionId(sessionId); - Forum forum = session.getForum(); - // get session from shared session. - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - Long userID = new Long(user.getUserID().longValue()); - if (!forum.getRunOffline() && !forum.isAllowNewTopic()) { + return mapping.findForward("success"); + } - List list = forumService.getRootTopics(sessionId); - for (MessageDTO msgDto : list) { - Long topicId = msgDto.getMessage().getUid(); - int numOfPostsInTopic = forumService.getNumOfPostsByTopic(userID, topicId); - if (numOfPostsInTopic < forum.getMinimumReply()) { - //create error - ActionMessages errors = new ActionMessages(); - errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.less.mini.post", forum.getMinimumReply())); - saveErrors(request, errors); + /** + * Sets the visibility of a message by updating the hide flag for a message + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + public ActionForward updateMessageHideFlag(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { - // get all root topic to display on init page - List rootTopics = forumService.getRootTopics(sessionId); - request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); - request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMapID); - return false; - } + Long msgId = new Long(WebUtil.readLongParam(request, ForumConstants.ATTR_TOPIC_ID)); + Boolean hideFlag = new Boolean(WebUtil.readBooleanParam(request, "hideFlag")); + forumService = getForumManager(); - } - } - return true; - } + // TODO Skipping permissions for now, currently having issues with default learning designs not having an + // create_by field + // Long sessionId = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_SESSION_ID); + // check if the user has permission to hide posts. + // ForumToolSession toolSession = forumService + // .getSessionBySessionId(sessionId); + // + // Forum forum = toolSession.getForum(); + // ForumUser currentUser = getCurrentUser(request,sessionId); + // ForumUser forumCreatedBy = forum.getCreatedBy(); - /** - * This method will set flag in message DTO: - *
  • If this topic is created by current login user, then set Author mark - * true.
  • - * - * @param msgDtoList - */ - private void updateMesssageFlag(List msgDtoList) { - // set current user to web page, so that can display "edit" button - // correct. Only author alow to edit. - HttpSession ss = SessionManager.getSession(); - // get back login user DTO - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + // we should be looking at whether a user is a teacher and more specifically staff + // if (currentUser.getUserId().equals(forumCreatedBy.getUserId())) { + forumService.updateMessageHideFlag(msgId, hideFlag.booleanValue()); + // } else { + // log.info(currentUser + "does not have permission to hide/show postings in forum: " + forum.getUid()); + // log.info("Forum created by :" + forumCreatedBy.getUid() + ", Current User is: " + currentUser.getUid()); + // } - Long currUserId = new Long(user.getUserID().intValue()); - Iterator iter = msgDtoList.iterator(); - while (iter.hasNext()) { - MessageDTO dto = (MessageDTO) iter.next(); - if (dto.getMessage().getCreatedBy() != null && currUserId.equals(dto.getMessage().getCreatedBy().getUserId())) { - dto.setAuthor(true); - } - else { - dto.setAuthor(false); - } + // echo back this topic thread into page + Long rootTopicId = forumService.getRootTopicId(msgId); + List msgDtoList = forumService.getTopicThread(rootTopicId); + updateMesssageFlag(msgDtoList); + request.setAttribute(ForumConstants.AUTHORING_TOPIC_THREAD, msgDtoList); + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, WebUtil.readStrParam(request, + ForumConstants.ATTR_SESSION_MAP_ID)); + + return mapping.findForward("success"); + } + + // ========================================================================================== + // Utility methods + // ========================================================================================== + /** + * Validation method to check whether user posts meet minimum number. + */ + private boolean validateBeforeFinish(HttpServletRequest request, String sessionMapID) { + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + Long sessionId = (Long) sessionMap.get(AttributeNames.PARAM_TOOL_SESSION_ID); + + ForumToolSession session = forumService.getSessionBySessionId(sessionId); + Forum forum = session.getForum(); + // get session from shared session. + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + Long userID = new Long(user.getUserID().longValue()); + if (!forum.getRunOffline() && !forum.isAllowNewTopic()) { + + List list = forumService.getRootTopics(sessionId); + for (MessageDTO msgDto : list) { + Long topicId = msgDto.getMessage().getUid(); + int numOfPostsInTopic = forumService.getNumOfPostsByTopic(userID, topicId); + if (numOfPostsInTopic < forum.getMinimumReply()) { + // create error + ActionMessages errors = new ActionMessages(); + errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error.less.mini.post", forum + .getMinimumReply())); + saveErrors(request, errors); + + // get all root topic to display on init page + List rootTopics = forumService.getRootTopics(sessionId); + request.setAttribute(ForumConstants.AUTHORING_TOPICS_LIST, rootTopics); + request.setAttribute(ForumConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return false; } - } - /** - * @param topicId - * @return - */ - private MessageDTO getTopic(Long topicId) { - // get Topic content according to TopicID - forumService = getForumManager(); - MessageDTO topic = MessageDTO.getMessageDTO(forumService.getMessage(topicId)); - return topic; + } } + return true; + } - /** - * Get login user information from system level session. Check it whether it - * exists in database or not, and save it if it does not exists. Return an - * instance of PO of ForumUser. - * - * @param request - * @param sessionId - * @return Current user instance - */ - private ForumUser getCurrentUser(HttpServletRequest request, Long sessionId) { - // get login user (author) - HttpSession ss = SessionManager.getSession(); - // get back login user DTO - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - ForumUser forumUser = forumService.getUserByUserAndSession(new Long(user.getUserID().intValue()), sessionId); - if (forumUser == null) { - // if user not exist, create new one in database - ForumToolSession session = forumService.getSessionBySessionId(sessionId); - forumUser = new ForumUser(user, session); - forumService.createUser(forumUser); - } - return forumUser; + /** + * This method will set flag in message DTO: + *
  • If this topic is created by current login user, then set Author mark true.
  • + * + * @param msgDtoList + */ + private void updateMesssageFlag(List msgDtoList) { + // set current user to web page, so that can display "edit" button + // correct. Only author alow to edit. + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + + Long currUserId = new Long(user.getUserID().intValue()); + Iterator iter = msgDtoList.iterator(); + while (iter.hasNext()) { + MessageDTO dto = (MessageDTO) iter.next(); + if (dto.getMessage().getCreatedBy() != null + && currUserId.equals(dto.getMessage().getCreatedBy().getUserId())) { + dto.setAuthor(true); + } else { + dto.setAuthor(false); + } } + } - /** - * Get Forum Service. - * - * @return - */ - private IForumService getForumManager() { - if (forumService == null) { - WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - forumService = (IForumService) wac.getBean(ForumConstants.FORUM_SERVICE); - } - return forumService; + /** + * @param topicId + * @return + */ + private MessageDTO getTopic(Long topicId) { + // get Topic content according to TopicID + forumService = getForumManager(); + MessageDTO topic = MessageDTO.getMessageDTO(forumService.getMessage(topicId)); + return topic; + } + + /** + * Get login user information from system level session. Check it whether it exists in database or not, and save it + * if it does not exists. Return an instance of PO of ForumUser. + * + * @param request + * @param sessionId + * @return Current user instance + */ + private ForumUser getCurrentUser(HttpServletRequest request, Long sessionId) { + // get login user (author) + HttpSession ss = SessionManager.getSession(); + // get back login user DTO + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + ForumUser forumUser = forumService.getUserByUserAndSession(new Long(user.getUserID().intValue()), sessionId); + if (forumUser == null) { + // if user not exist, create new one in database + ForumToolSession session = forumService.getSessionBySessionId(sessionId); + forumUser = new ForumUser(user, session); + forumService.createUser(forumUser); } + return forumUser; + } - /** - * @param messageForm - * @param message - */ - private void setAttachment(MessageForm messageForm, Message message) { - if (messageForm.getAttachmentFile() != null && !StringUtils.isBlank(messageForm.getAttachmentFile().getFileName())) { - forumService = getForumManager(); - Attachment att = forumService.uploadAttachment(messageForm.getAttachmentFile()); - Set attSet = message.getAttachments(); - if (attSet == null) { - attSet = new HashSet(); - } - // only allow one attachment, so replace whatever - attSet.clear(); - attSet.add(att); - message.setAttachments(attSet); - } - else if (!messageForm.isHasAttachment()) { - //user already called deleteAttachment in AJAX call - if (message.getAttachments() != null) { - Set atts = message.getAttachments(); - atts.clear(); - message.setAttachments(atts); - } - else { - message.setAttachments(null); - } - } + /** + * Get Forum Service. + * + * @return + */ + private IForumService getForumManager() { + if (forumService == null) { + WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() + .getServletContext()); + forumService = (IForumService) wac.getBean(ForumConstants.FORUM_SERVICE); } + return forumService; + } - private SessionMap getSessionMap(HttpServletRequest request, MessageForm messageForm) { - SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(messageForm.getSessionMapID()); - return sessionMap; + /** + * @param messageForm + * @param message + */ + private void setAttachment(MessageForm messageForm, Message message) { + if (messageForm.getAttachmentFile() != null + && !StringUtils.isBlank(messageForm.getAttachmentFile().getFileName())) { + forumService = getForumManager(); + Attachment att = forumService.uploadAttachment(messageForm.getAttachmentFile()); + Set attSet = message.getAttachments(); + if (attSet == null) { + attSet = new HashSet(); + } + // only allow one attachment, so replace whatever + attSet.clear(); + attSet.add(att); + message.setAttachments(attSet); + } else if (!messageForm.isHasAttachment()) { + // user already called deleteAttachment in AJAX call + if (message.getAttachments() != null) { + Set atts = message.getAttachments(); + atts.clear(); + message.setAttachments(atts); + } else { + message.setAttachments(null); + } } + } + private SessionMap getSessionMap(HttpServletRequest request, MessageForm messageForm) { + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(messageForm.getSessionMapID()); + return sessionMap; + } + }