Index: lams_learning/conf/language/lams/ApplicationResources.properties =================================================================== RCS file: /usr/local/cvsroot/lams_learning/conf/language/lams/ApplicationResources.properties,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_learning/conf/language/lams/ApplicationResources.properties 12 Mar 2007 05:41:15 -0000 1.1.2.1 +++ lams_learning/conf/language/lams/ApplicationResources.properties 28 Mar 2007 06:42:13 -0000 1.1.2.2 @@ -73,6 +73,6 @@ label.close.button =Close mynotes.journals.title =Journals mynotes.entry.no.title.label =No Title +message.progress.broken=An error has occurred and you cannot continue with LAMS recalculating your current activity. Please select "Resume" or close and reopen this window to continue. - #======= End labels: Exported 67 labels for en AU ===== Index: lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java,v diff -u -r1.21.4.1 -r1.21.4.2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java 13 Feb 2007 05:43:30 -0000 1.21.4.1 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java 28 Mar 2007 06:41:46 -0000 1.21.4.2 @@ -92,25 +92,36 @@ /** * Method determines the start point for a learner when they begin a Lesson. - * @param learner the User who is starting the Lesson. - * @param lesson the Lesson the learner is starting. + * + * It is also reused to calculate where the learner should be should the progress + * "go wrong". For example, the teacher does live edit and the learner moves to + * the stop gate created for the live edit. When the edit is completed, the stop + * gate is removed. But now there is no current activity for the learner. + * + * @param LearnerProgress The user's progress details for the User who is starting the Lesson. + * @return LearnerProgress The updated user's progress details. * @throws ProgressException if the start point cannot be calculated successfully. */ - public void setUpStartPoint(User learner, Lesson lesson, - LearnerProgress progress) throws ProgressException + public LearnerProgress setUpStartPoint(LearnerProgress progress) throws ProgressException { - LearningDesign ld = lesson.getLearningDesign(); + LearningDesign ld = progress.getLesson().getLearningDesign(); if(ld.getFirstActivity()==null) throw new ProgressException("Could not find first activity for " +"learning design ["+ld.getTitle()+"], id[" +ld.getLearningDesignId().longValue() +"]"); - progress.setCurrentActivity(ld.getFirstActivity()); - progress.setNextActivity(ld.getFirstActivity()); - setActivityAttempted(progress, ld.getFirstActivity()); + if ( progress.getCompletedActivities().contains(ld.getFirstActivity()) ) { + // special case - recalculating the appropriate current activity. + return calculateProgress(progress.getUser(), ld.getFirstActivity(), progress); + } else { + progress.setCurrentActivity(ld.getFirstActivity()); + progress.setNextActivity(ld.getFirstActivity()); + setActivityAttempted(progress, ld.getFirstActivity()); + return progress; + } } /** Set the current activity as attempted. If it is a parallel activity, mark its children as attempted too. */ 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.61.4.1 -r1.61.4.2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java 13 Feb 2007 07:11:49 -0000 1.61.4.1 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java 28 Mar 2007 06:41:55 -0000 1.61.4.2 @@ -53,7 +53,6 @@ import org.lamsfoundation.lams.lesson.dto.LessonDTO; import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.lesson.service.LessonServiceException; -import org.lamsfoundation.lams.monitoring.service.MonitoringServiceException; import org.lamsfoundation.lams.tool.ToolSession; import org.lamsfoundation.lams.tool.dao.IToolSessionDAO; import org.lamsfoundation.lams.tool.exception.LamsToolServiceException; @@ -243,7 +242,7 @@ try { - progressEngine.setUpStartPoint(learner, lesson,learnerProgress); + progressEngine.setUpStartPoint(learnerProgress); } catch (ProgressException e) { @@ -253,15 +252,31 @@ //Use TimeStamp rather than Date directly to keep consistent with Hibnerate persiste object. learnerProgress.setStartDate(new Timestamp(new Date().getTime())); learnerProgressDAO.saveLearnerProgress(learnerProgress); + } else { + + Activity currentActivity = learnerProgress.getCurrentActivity(); + if ( currentActivity == null ) { + // something may have gone wrong and we need to recalculate the current activity + try + { + progressEngine.setUpStartPoint(learnerProgress); + } + catch (ProgressException e) + { + log.error("error occurred in 'setUpStartPoint':"+e.getMessage()); + throw new LearnerServiceException(e.getMessage()); + } + } + + //The restarting flag should be setup when the learner hit the exit + //button. But it is possible that user exit by closing the browser, + //In this case, we set the restarting flag again. + if(!learnerProgress.isRestarting()) + { + learnerProgress.setRestarting(true); + learnerProgressDAO.updateLearnerProgress(learnerProgress); + } } - //The restarting flag should be setup when the learner hit the exit - //button. But it is possible that user exit by closing the browser, - //In this case, we set the restarting flag again. - else if(!learnerProgress.isRestarting()) - { - learnerProgress.setRestarting(true); - learnerProgressDAO.updateLearnerProgress(learnerProgress); - } return learnerProgress; } @@ -402,11 +417,19 @@ // being available in the context. Hence it is defined in the ILearnerService interface, not the IFullLearnerService // interface. If it calls any other methods then it mustn't use anything on the ICoreLearnerService interface. + String returnURL = null; + ToolSession toolSession = lamsCoreToolService.getToolSessionById(toolSessionId); - // in the future, we might want to see if the entire tool session is completed at this point. - - String returnURL = completeActivity(new Integer(learnerId.intValue()), toolSession.getToolActivity(), toolSession.getLesson().getLessonId()); + if ( toolSession == null ) { + // something has gone wrong - maybe due to Live Edit. The tool session supplied by the tool doesn't exist. + // have to go to a "can't do anything" screen and the user will have to hit resume. + returnURL = ActivityMapping.getProgressBrokenURL(); + } else { + // in the future, we might want to see if the entire tool session is completed at this point. + returnURL = completeActivity(new Integer(learnerId.intValue()), toolSession.getToolActivity(), toolSession.getLesson().getLessonId()); + } + if ( log.isDebugEnabled() ) { log.debug("Moving onto next activity after tool session id "+toolSessionId+" learnerId "+learnerId+" url is "+returnURL); } @@ -419,14 +442,15 @@ * @see org.lamsfoundation.lams.learning.service.ICoreLearnerService#completeActivity(java.lang.Integer, java.lang.Long, java.lang.Long) */ public String completeActivity(Integer learnerId,Long activityId,Long lessonId) { - Activity activity = getActivity(activityId); + Activity activity = activityId!=null ? getActivity(activityId) : null; return completeActivity(learnerId, activity,lessonId); } /** + * @throws * @see org.lamsfoundation.lams.learning.service.ICoreLearnerService#completeActivity(java.lang.Integer, org.lamsfoundation.lams.learningdesign.Activity, java.lang.Long ) */ - public String completeActivity(Integer learnerId,Activity activity,Long lessonId) + public String completeActivity(Integer learnerId,Activity activity,Long lessonId) { LearnerProgress currentProgress = getProgress(new Integer(learnerId.intValue()), lessonId); @@ -439,7 +463,19 @@ // same object for tool session or current progress and user is cached via login, not userid. String returnURL = null; // bottleneck synchronized (this) { - if (currentProgress.getCompletedActivities().contains(activity)) { + if (activity==null ) { + try { + LearnerProgress nextLearnerProgress = progressEngine.setUpStartPoint(currentProgress); + returnURL = activityMapping.getProgressURL(nextLearnerProgress); + } catch (ProgressException e) { + log.error("error occurred in 'setUpStartPoint':"+e.getMessage(),e); + throw new LearnerServiceException(e); + } catch (UnsupportedEncodingException e) { + log.error("error occurred in 'getProgressURL':"+e.getMessage(),e); + throw new LearnerServiceException(e); + } + + } else if (currentProgress.getCompletedActivities().contains(activity)) { // return close window url returnURL = ActivityMapping.getCloseURL(); @@ -452,8 +488,8 @@ } catch (UnsupportedEncodingException e) { - log.error("error occurred in 'getProgressURL':"+e.getMessage()); - throw new LearnerServiceException(e.getMessage()); + log.error("error occurred in 'getProgressURL':"+e.getMessage(),e); + throw new LearnerServiceException(e); } } //} Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/ChooseActivityAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/ChooseActivityAction.java,v diff -u -r1.13 -r1.13.4.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/ChooseActivityAction.java 29 Oct 2006 23:29:58 -0000 1.13 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/ChooseActivityAction.java 28 Mar 2007 06:41:35 -0000 1.13.4.1 @@ -71,25 +71,27 @@ ICoreLearnerService learnerService = getLearnerService(); // Get learner and lesson details. - Integer learner = LearningWebUtil.getUserId(); + Integer learnerId = LearningWebUtil.getUserId(); LearnerProgress progress = LearningWebUtil.getLearnerProgress(request,learnerService); Lesson lesson = progress.getLesson(); Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); - - if (activity == null) { - log.error(className+": No activity in request or session"); - return mapping.findForward(ActivityMapping.ERROR); - } - progress = learnerService.chooseActivity(learner, lesson.getLessonId(), activity); + if (activity != null) { + progress = learnerService.chooseActivity(learnerId, lesson.getLessonId(), activity); + } else { + // Something has gone wrong - maybe due to Live Edit. Need to recalculate their current location. + progress = learnerService.joinLesson(learnerId, lesson.getLessonId()); + } + LearningWebUtil.putLearnerProgressInRequest(request,progress); - // need to do the choose first as the chooseActivity changes the progress details + // need to do the choose first as the chooseActivity / joinLesson changes the progress details setupProgressString(actionForm, request); ActionForward forward = actionMappings.getActivityForward(activity, progress, true); return forward; + } } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java,v diff -u -r1.14 -r1.14.4.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java 29 Oct 2006 23:29:58 -0000 1.14 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/CompleteActivityAction.java 28 Mar 2007 06:41:35 -0000 1.14.4.1 @@ -36,6 +36,8 @@ import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.lesson.LearnerProgress; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.util.AttributeNames; /** * @author daveg @@ -52,10 +54,7 @@ /** * Sets the current activity as complete and uses the progress engine to find - * the next activity (may be null). Note that the activity being completed may be - * part of a parallel activity. - * Forwards onto the required display action (displayToolActivity, - * displayParallelActivity, etc.). + * the next activity (may be null). Currently only used when completing an optional activity. */ public ActionForward execute( ActionMapping mapping, @@ -78,20 +77,24 @@ Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); if (activity == null) { - log.error(className+": No activity in request or session"); - return mapping.findForward(ActivityMapping.ERROR); - } + // something has gone wrong - maybe due to Live Edit. No more activity so try to resume + Long lessonID = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); + progress = learnerService.joinLesson(learnerId, lessonID); - // Set activity as complete - try { - progress = learnerService.calculateProgress(activity, learnerId); + } else { + + // Set activity as complete + try { + progress = learnerService.calculateProgress(activity, learnerId); + } + catch (LearnerServiceException e) { + return mapping.findForward("error"); + } + LearningWebUtil.putActivityInRequest(request, progress.getNextActivity(), learnerService); } - catch (LearnerServiceException e) { - return mapping.findForward("error"); - } - LearningWebUtil.putActivityInRequest(request, progress.getNextActivity(), learnerService); + LearningWebUtil.putLearnerProgressInRequest(request,progress); - + // need to do the calculateProgress first as the chooseActivity changes the progress details setupProgressString(actionForm, request); Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java,v diff -u -r1.15 -r1.15.4.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java 29 Oct 2006 23:29:58 -0000 1.15 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java 28 Mar 2007 06:41:35 -0000 1.15.4.1 @@ -112,6 +112,7 @@ form.setMaximum(optionsActivity.getMaxNumberOfOptionsNotNull().intValue()); form.setDescription(optionsActivity.getDescription()); form.setTitle(optionsActivity.getTitle()); + form.setLessonID(learnerProgress.getLesson().getLessonId()); this.saveToken(request); Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GateAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GateAction.java,v diff -u -r1.14.4.1 -r1.14.4.2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GateAction.java 1 Mar 2007 21:33:14 -0000 1.14.4.1 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GateAction.java 28 Mar 2007 06:41:35 -0000 1.14.4.2 @@ -119,30 +119,42 @@ { boolean forceGate = WebUtil.readBooleanParam(request,PARAM_FORCE_GATE_OPEN,false); Long activityId = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long lessonId = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); //initialize service object ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); Activity activity = learnerService.getActivity(activityId); - Lesson lesson = learnerService.getLessonByActivity(activity); - User learner = LearningWebUtil.getUser(learnerService); - - Integer totalNumActiveLearners = learnerService.getCountActiveLearnersByLesson(lesson.getLessonId()); - //knock the gate - boolean gateOpen = learnerService.knockGate(activityId,learner,forceGate); - - // if the gate is open, let the learner go to the next activity ( updating the cached learner progress on the way ) - // pass only the ids in to completeActivity, so that the service level looks up the objects. - // if we reuse our cached entries, hibernate may throw session errors (if the objects are CGLIB entities). - if(gateOpen) - { - String nextActivityUrl = learnerService.completeActivity(learner.getUserId(),activityId,lesson.getLessonId()); + + if ( activity == null ) { + // if this is a temporary stop gate, created for Live Edit, the activity will have been deleted when Live Edit finished + // so manually resume the progress. The completeActivity code can cope with a missing activity. + String nextActivityUrl = learnerService.completeActivity(LearningWebUtil.getUserId(),(Activity)null,lessonId); response.sendRedirect(nextActivityUrl); return null; + + } else { + + User learner = LearningWebUtil.getUser(learnerService); + Lesson lesson = learnerService.getLesson(lessonId); + + Integer totalNumActiveLearners = learnerService.getCountActiveLearnersByLesson(lesson.getLessonId()); + //knock the gate + boolean gateOpen = learnerService.knockGate(activityId,learner,forceGate); + + // if the gate is open, let the learner go to the next activity ( updating the cached learner progress on the way ) + // pass only the ids in to completeActivity, so that the service level looks up the objects. + // if we reuse our cached entries, hibernate may throw session errors (if the objects are CGLIB entities). + if(gateOpen) + { + String nextActivityUrl = learnerService.completeActivity(learner.getUserId(),activityId,lesson.getLessonId()); + response.sendRedirect(nextActivityUrl); + return null; + } + //if the gate is closed, ask the learner to wait ( updating the cached learner progress on the way ) + else { + return findViewByGateType(mapping, (DynaActionForm)form, activity, totalNumActiveLearners, lesson); + } } - //if the gate is closed, ask the learner to wait ( updating the cached learner progress on the way ) - else { - return findViewByGateType(mapping, (DynaActionForm)form, activity, totalNumActiveLearners, lesson.isPreviewLesson()); - } } //--------------------------------------------------------------------- @@ -164,13 +176,14 @@ DynaActionForm gateForm, Activity gate, Integer totalNumActiveLearners, - boolean isPreviewLesson) + Lesson lesson) { //dispatch the view according to the type of the gate. if ( gate != null ) { gateForm.set("totalLearners",totalNumActiveLearners); - gateForm.set("previewLesson",isPreviewLesson); - gateForm.set("activityId",gate.getActivityId()); + gateForm.set("previewLesson",lesson.isPreviewLesson()); + gateForm.set(AttributeNames.PARAM_ACTIVITY_ID,gate.getActivityId()); + gateForm.set(AttributeNames.PARAM_LESSON_ID, lesson.getLessonId()); if(gate.isSynchGate()) return viewSynchGate(mapping,gateForm,(SynchGateActivity)gate); else if(gate.isScheduleGate()) Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java,v diff -u -r1.37 -r1.37.2.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java 29 Jan 2007 04:08:09 -0000 1.37 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java 28 Mar 2007 06:41:35 -0000 1.37.2.1 @@ -45,9 +45,6 @@ import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.dto.LearnerProgressDTO; import org.lamsfoundation.lams.lesson.dto.LessonDTO; -import org.lamsfoundation.lams.monitoring.MonitoringConstants; -import org.lamsfoundation.lams.monitoring.service.IMonitoringService; -import org.lamsfoundation.lams.monitoring.service.MonitoringServiceProxy; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.util.audit.IAuditService; Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/ActivityMapping.java =================================================================== RCS file: /usr/local/cvsroot/lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/ActivityMapping.java,v diff -u -r1.31 -r1.31.2.1 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/ActivityMapping.java 19 Jan 2007 03:59:03 -0000 1.31 +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/ActivityMapping.java 28 Mar 2007 06:41:36 -0000 1.31.2.1 @@ -371,8 +371,12 @@ public static String getCloseURL() { String lamsUrl = Configuration.get(ConfigurationKeys.SERVER_URL) + LEARNING; String closeUrl = lamsUrl + "/close.do"; - return closeUrl; } + public static String getProgressBrokenURL() { + String lamsUrl = Configuration.get(ConfigurationKeys.SERVER_URL) + LEARNING; + String closeUrl = lamsUrl + "/progressBroken.do"; + return closeUrl; + } } \ No newline at end of file Index: lams_learning/web/optionsActivity.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_learning/web/optionsActivity.jsp,v diff -u -r1.24 -r1.24.4.1 --- lams_learning/web/optionsActivity.jsp 16 Nov 2006 01:07:33 -0000 1.24 +++ lams_learning/web/optionsActivity.jsp 28 Mar 2007 06:43:01 -0000 1.24.4.1 @@ -114,8 +114,8 @@ - " /> - + + Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_learning/web/progressBroken.jsp'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_learning/web/WEB-INF/struts/struts-config.xml =================================================================== RCS file: /usr/local/cvsroot/lams_learning/web/WEB-INF/struts/Attic/struts-config.xml,v diff -u -r1.34 -r1.34.4.1 --- lams_learning/web/WEB-INF/struts/struts-config.xml 29 Sep 2006 06:30:32 -0000 1.34 +++ lams_learning/web/WEB-INF/struts/struts-config.xml 28 Mar 2007 06:42:53 -0000 1.34.4.1 @@ -33,7 +33,8 @@ - + + @@ -145,6 +146,11 @@ redirect="false" /> + - - - - + Index: lams_learning/web/WEB-INF/struts/tiles-defs.xml =================================================================== RCS file: /usr/local/cvsroot/lams_learning/web/WEB-INF/struts/Attic/tiles-defs.xml,v diff -u -r1.25 -r1.25.4.1 --- lams_learning/web/WEB-INF/struts/tiles-defs.xml 4 Oct 2006 08:05:08 -0000 1.25 +++ lams_learning/web/WEB-INF/struts/tiles-defs.xml 28 Mar 2007 06:42:53 -0000 1.25.4.1 @@ -81,6 +81,10 @@ + + + + Index: lams_learning/web/gate/gateNext.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_learning/web/gate/gateNext.jsp,v diff -u -r1.7 -r1.7.2.1 --- lams_learning/web/gate/gateNext.jsp 5 Jan 2007 03:23:45 -0000 1.7 +++ lams_learning/web/gate/gateNext.jsp 28 Mar 2007 06:42:36 -0000 1.7.2.1 @@ -1,4 +1,4 @@ - +

Index: lams_learning/web/layout/gateLayout.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_learning/web/layout/gateLayout.jsp,v diff -u -r1.8 -r1.8.4.1 --- lams_learning/web/layout/gateLayout.jsp 17 Nov 2006 07:30:09 -0000 1.8 +++ lams_learning/web/layout/gateLayout.jsp 28 Mar 2007 06:42:36 -0000 1.8.4.1 @@ -38,7 +38,7 @@ <c:out value="${pageTitle}" /> - +