Index: lams_learning/src/java/org/lamsfoundation/lams/learning/learningApplicationContext.xml =================================================================== diff -u -rdd42ee56aadaa0f237dd0766a197cb418f182b7e -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/learningApplicationContext.xml (.../learningApplicationContext.xml) (revision dd42ee56aadaa0f237dd0766a197cb418f182b7e) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/learningApplicationContext.xml (.../learningApplicationContext.xml) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -48,6 +48,8 @@ PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED + PROPAGATION_REQUIRED + PROPAGATION_REQUIRED Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java =================================================================== diff -u -rdd42ee56aadaa0f237dd0766a197cb418f182b7e -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java (.../ICoreLearnerService.java) (revision dd42ee56aadaa0f237dd0766a197cb418f182b7e) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java (.../ICoreLearnerService.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -26,8 +26,6 @@ import java.util.List; -import org.lamsfoundation.lams.learning.progress.ProgressEngine; -import org.lamsfoundation.lams.learning.progress.ProgressException; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.GateActivity; @@ -268,11 +266,18 @@ * @param lesson current lesson. * @param BranchingActivity the branching activity * @param learnerId the learner who triggers the grouping. - * @param forceBranch if true and the lesson is a preview lesson then the branching is done irrespective of - * whether the teacher has set up all the mappings, allocated learner to branch, etc - * @return SequenceActivity that forms the branch if known, null if still awaiting teacher input. * @throws LearnerServiceException */ public SequenceActivity determineBranch(Lesson lesson, BranchingActivity branchingActivity, Integer learnerId) throws LearnerServiceException; + /** + * Select a particular branch - we are in preview mode and the author has selected a particular activity. + * @param lesson current lesson. + * @param BranchingActivity the branching activity + * @param learnerId the learner who triggers the grouping. + * @return branchId of the desired branch + * @throws LearnerServiceException + */ + public SequenceActivity selectBranch(Lesson lesson, BranchingActivity branchingActivity, Integer learnerId, Long branchId) throws LearnerServiceException; + } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java =================================================================== diff -u -r9e07db992848ed0a7724d5c6471af535465097a7 -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision 9e07db992848ed0a7724d5c6471af535465097a7) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -29,6 +29,7 @@ import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.apache.log4j.Logger; import org.lamsfoundation.lams.learning.progress.ProgressEngine; @@ -41,7 +42,6 @@ import org.lamsfoundation.lams.learningdesign.GroupBranchActivityEntry; import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.GroupingActivity; -import org.lamsfoundation.lams.learningdesign.ParallelActivity; import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; @@ -551,7 +551,7 @@ } else if ( forceGrouping ) { // preview case for chosen grouping Lesson lesson = getLesson(lessonId); - groupingDone = forceGrouping(lesson, grouping, learner); + groupingDone = forceGrouping(lesson, grouping, null, learner); } } @@ -566,18 +566,17 @@ return groupingDone; } - private boolean forceGrouping(Lesson lesson, Grouping grouping, User learner) { + private boolean forceGrouping(Lesson lesson, Grouping grouping, Group group, User learner) { boolean groupingDone = false; if ( lesson.isPreviewLesson() ) { ArrayList learnerList = new ArrayList(); learnerList.add(learner); - lessonService.performGrouping(grouping, (String)null, learnerList); + lessonService.performGrouping(grouping, group!=null?group.getGroupId():null, learnerList); groupingDone = true; } return groupingDone; } - /** * @see org.lamsfoundation.lams.learning.service.ICoreLearnerService#knockGate(java.lang.Long, org.lamsfoundation.lams.usermanagement.User) */ @@ -748,31 +747,15 @@ // If the user is in a group, then check if the group is assigned to a sequence activity. If it // is then we are done and we return the sequence Group group = grouping.getGroupBy(learner); - if ( group == null && lesson.isPreviewLesson()) { - // if it is preview, we force the user into a group. - if (forceGrouping(lesson, grouping, learner) ) { - group = grouping.getGroupBy(learner); + if ( group != null ) { + if ( group.getBranchActivities() != null ) { + Iterator branchesIterator = group.getBranchActivities().iterator(); + while (sequenceActivity==null && branchesIterator.hasNext()) { + GroupBranchActivityEntry branchActivityEntry = (GroupBranchActivityEntry) branchesIterator.next(); + if ( branchActivityEntry.getBranchingActivity().equals(branchingActivity) ) + sequenceActivity = branchActivityEntry.getBranchSequenceActivity(); + } } - if ( log.isDebugEnabled() ) - log.debug("Forced the user into group "+group+" for branching purposes."); - } - - if ( group != null && group.getBranchActivities() != null ) { - Iterator branchesIterator = group.getBranchActivities().iterator(); - while (sequenceActivity==null && branchesIterator.hasNext()) { - GroupBranchActivityEntry branchActivityEntry = (GroupBranchActivityEntry) branchesIterator.next(); - if ( branchActivityEntry.getBranchingActivity().equals(branchingActivity) ) - sequenceActivity = branchActivityEntry.getBranchSequenceActivity(); - } - if ( sequenceActivity == null && lesson.isPreviewLesson()) { - // how do we force them into a branch ? do we just pick one ? is that good enough for preview ? - Iterator iter= branchingActivity.getActivities().iterator(); - if (iter.hasNext()) { - sequenceActivity = (SequenceActivity) iter.next(); - } - if ( log.isDebugEnabled() ) - log.debug("Forced the user into branch"+sequenceActivity); - } } if ( sequenceActivity != null ) { @@ -788,7 +771,79 @@ return sequenceActivity; } - public ProgressEngine getProgressEngine() { + /** + * Select a particular branch - we are in preview mode and the author has selected a particular activity. + * + * @throws LearnerServiceException + * @see org.lamsfoundation.lams.learning.service.ICoreLearnerService#determineBranch(org.lamsfoundation.lams.lesson.Lesson, org.lamsfoundation.lams.learningdesign.BranchingActivity, java.lang.Integer) + */ + public SequenceActivity selectBranch(Lesson lesson, BranchingActivity branchingActivity, Integer learnerId, Long branchId) throws LearnerServiceException { + + User learner = (User)userManagementService.findById(User.class,learnerId); + if ( learner == null ) { + String error = "selectBranch: learner "+learnerId+" does not exist. Cannot determine branch."; + log.error(error); + throw new LearnerServiceException(error); + } + + // Find the matching branch - all the child activities in the branching activity + // should be sequence activities. + SequenceActivity selectedBranch = null; + Iterator iter = branchingActivity.getActivities().iterator(); + while (selectedBranch==null && iter.hasNext()) { + SequenceActivity aBranch = (SequenceActivity) iter.next(); + if ( aBranch.getActivityId().equals(branchId) ) { + selectedBranch = aBranch; + } + } + + if ( selectedBranch != null ) { + + Set groups = selectedBranch.getGroupsForBranch(); + Grouping grouping = branchingActivity.getGrouping(); + + // Does this matching branch have any groups? If so, see if the learner is in + // the appropriate group and add them if necessary. + if ( groups != null && groups.size() > 0) { + boolean isInGroup = false; + Group aGroup = null; + Iterator groupIter = groups.iterator(); + while (!isInGroup && groupIter.hasNext()) { + aGroup = (Group) groupIter.next(); + isInGroup = aGroup.hasLearner(learner); + } + + // If the learner is not in the appropriate group, then force the learner in the + // last group we checked. this will only work if the user is in preview. + if (!isInGroup) { + if ( ! forceGrouping(lesson, grouping, aGroup, learner) ) { + String error = "selectBranch: learner "+learnerId+" cannot be added to the group "+aGroup+" for the branch " + +selectedBranch+" for the lesson "+lesson.getLessonName()+" preview is "+lesson.isPreviewLesson() + +". This will only work if preview is true."; + log.error(error); + throw new LearnerServiceException(error); + } + } + + // if no groups exist, then create one and assign it to the branch. + } else { + Group group = lessonService.createGroup(grouping, selectedBranch.getTitle()); + group.allocateBranchToGroup(null,null, selectedBranch, branchingActivity); + } + groupingDAO.update(grouping); + + if ( log.isDebugEnabled()) { + log.debug("Found branch "+selectedBranch.getActivityId()+":"+ selectedBranch.getTitle() + +" for branching activity "+branchingActivity.getActivityId()+":"+ branchingActivity.getTitle() + +" for learner "+learner.getUserId()+":"+learner.getLogin()); + } + } + + return selectedBranch; + } + + + public ProgressEngine getProgressEngine() { return progressEngine; } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/BranchingActivityAction.java =================================================================== diff -u -rccf0c98665da622cc43ff39393de652596752cdf -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/BranchingActivityAction.java (.../BranchingActivityAction.java) (revision ccf0c98665da622cc43ff39393de652596752cdf) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/BranchingActivityAction.java (.../BranchingActivityAction.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -24,6 +24,11 @@ /* $$Id$$ */ package org.lamsfoundation.lams.learning.web.action; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -38,8 +43,10 @@ import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.lesson.LearnerProgress; +import org.lamsfoundation.lams.learning.web.bean.ActivityURL; import org.lamsfoundation.lams.learning.web.util.ActivityMapping; import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; +import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; /** @@ -55,11 +62,16 @@ * validate="false" * * @struts:action-forward name="displayBranchingWait" path=".branchingActivityWait" + * @struts:action-forward name="displayBranchingPreview" path=".branchingActivityPreview" * */ public class BranchingActivityAction extends LamsDispatchAction { - private ICoreLearnerService learnerService = null; + + /** Input parameter. Boolean value */ + public static final String PARAM_FORCE_GROUPING = "force"; + + private ICoreLearnerService learnerService = null; protected ICoreLearnerService getLearnerService() { if (learnerService == null) @@ -83,6 +95,7 @@ LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); Integer learnerId = LearningWebUtil.getUserId(); + boolean forceGroup = WebUtil.readBooleanParam(request,PARAM_FORCE_GROUPING,false); ActionForward forward = null; @@ -100,25 +113,53 @@ SequenceActivity branch = learnerService.determineBranch(learnerProgress.getLesson(), branchingActivity, learnerId); - if ( branch == null ) { - // goto waiting page - DynaActionForm groupForm = (DynaActionForm)actionForm; - groupForm.set("activityID", activity.getActivityId()); - groupForm.set("progressID", learnerProgress.getLearnerProgressId()); - groupForm.set("previewLesson",learnerProgress.getLesson().isPreviewLesson()?Boolean.TRUE:Boolean.FALSE); - groupForm.set("showFinishButton", Boolean.TRUE); - groupForm.set("title", activity.getTitle()); + DynaActionForm branchForm = (DynaActionForm)actionForm; + branchForm.set("activityID", activity.getActivityId()); + branchForm.set("progressID", learnerProgress.getLearnerProgressId()); + branchForm.set("showFinishButton", Boolean.TRUE); + branchForm.set("title", activity.getTitle()); + + if ( learnerProgress.getLesson().isPreviewLesson() ) { + + // The preview version gives you a choice of branches + // If a "normal" branch can be determined based on the group, tool marks, etc then it is marked as the default branch + + branchForm.set("previewLesson",Boolean.TRUE); + forward = mapping.findForward("displayBranchingPreview"); + + List activityURLs = new ArrayList(); + Iterator i = branchingActivity.getActivities().iterator(); + int completedCount = 0; + while (i.hasNext()) { + Activity nextBranch = (Activity)i.next(); + ActivityURL activityURL = LearningWebUtil.getActivityURL( actionMappings, learnerProgress, + nextBranch, branch != null && branch.equals(nextBranch)); + if ( activityURL.isComplete() ) { + completedCount++; + } + activityURLs.add(activityURL); + } + branchForm.set("activityURLs",activityURLs); + branchForm.set("showNextButton", branchingActivity.getActivities().size() != completedCount ); + + LearningWebUtil.setupProgressInRequest(branchForm, request, learnerProgress); + + } else if ( branch == null ) { + + // show the learner waiting page + branchForm.set("previewLesson",Boolean.FALSE); + forward = mapping.findForward("displayBranchingWait"); + branchForm.set("showNextButton", Boolean.TRUE); if ( branchingActivity.isChosenBranchingActivity() ) { - groupForm.set("type", BranchingActivity.CHOSEN_TYPE); + branchForm.set("type", BranchingActivity.CHOSEN_TYPE); } else if ( branchingActivity.isGroupBranchingActivity() ) { - groupForm.set("type", BranchingActivity.GROUP_BASED_TYPE); + branchForm.set("type", BranchingActivity.GROUP_BASED_TYPE); } else if ( branchingActivity.isToolBranchingActivity() ) { - groupForm.set("type", BranchingActivity.TOOL_BASED_TYPE); + branchForm.set("type", BranchingActivity.TOOL_BASED_TYPE); } - forward = mapping.findForward("displayBranchingWait"); - LearningWebUtil.setupProgressInRequest(groupForm, request, learnerProgress); + LearningWebUtil.setupProgressInRequest(branchForm, request, learnerProgress); } else { // forward to the sequence activity. @@ -136,4 +177,55 @@ return forward; } + /** + * We are in the preview lesson and the author has selected a particular branch. Force it to take that branch. + */ + public ActionForward forceBranching( + ActionMapping mapping, + ActionForm actionForm, + HttpServletRequest request, + HttpServletResponse response) { + + ActivityMapping actionMappings = LearningWebUtil.getActivityMapping(this.getServlet().getServletContext()); + getLearnerService(); // initialise the learner service, if necessary + + LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); + Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); + Integer learnerId = LearningWebUtil.getUserId(); + ActionForward forward = null; + + if (activity == null) { + learnerProgress = learnerService.joinLesson(learnerId, learnerProgress.getLesson().getLessonId()); + forward = actionMappings.getActivityForward(activity, learnerProgress, true); + + } else if (!(activity instanceof BranchingActivity)) { + log.error(className+": activity not BranchingActivity "+activity.getActivityId()); + forward = mapping.findForward(ActivityMapping.ERROR); + + } else { + + BranchingActivity branchingActivity = (BranchingActivity)activity; + Long branchId = WebUtil.readLongParam(request, "branchID", false); + + SequenceActivity branch = learnerService.selectBranch(learnerProgress.getLesson(), + branchingActivity, learnerId, branchId); + + if ( branch == null ) { + log.error(className+": branch id from request is not valid. Activity id "+activity.getActivityId()+" branch id "+branchId); + forward = mapping.findForward(ActivityMapping.ERROR); + } + + // forward to the sequence activity. + if ( log.isDebugEnabled() ) { + log.debug("Branching: selecting the branch "+branch+" for user "+learnerId); + } + + // Set the branch as the current part of the sequence and display it + learnerProgress = learnerService.chooseActivity(learnerId, learnerProgress.getLesson().getLessonId(), branch); + forward = actionMappings.getActivityForward(branch, learnerProgress, true); + LearningWebUtil.putLearnerProgressInRequest(request,learnerProgress); + } + + return forward; + } } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java =================================================================== diff -u -r5863520d75343b47f77b05ad3bd7045a9a39af49 -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java (.../DisplayOptionsActivityAction.java) (revision 5863520d75343b47f77b05ad3bd7045a9a39af49) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/DisplayOptionsActivityAction.java (.../DisplayOptionsActivityAction.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -90,15 +90,8 @@ Iterator i = subActivities.iterator(); int completedCount = 0; while (i.hasNext()) { - Activity subActivity = (Activity)i.next(); - ActivityURL activityURL = new ActivityURL(); - String url = actionMappings.getActivityURL(subActivity); - activityURL.setUrl(url); - activityURL.setActivityId(subActivity.getActivityId()); - activityURL.setTitle(subActivity.getTitle()); - activityURL.setDescription(subActivity.getDescription()); - if (learnerProgress.getProgressState(subActivity) == LearnerProgress.ACTIVITY_COMPLETED) { - activityURL.setComplete(true); + ActivityURL activityURL = LearningWebUtil.getActivityURL( actionMappings, learnerProgress, (Activity)i.next(), false); + if ( activityURL.isComplete() ) { completedCount++; } activityURLs.add(activityURL); Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/bean/ActivityURL.java =================================================================== diff -u -r08950e1090443c3423a3d1c587416a2fccd8bbdf -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/bean/ActivityURL.java (.../ActivityURL.java) (revision 08950e1090443c3423a3d1c587416a2fccd8bbdf) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/bean/ActivityURL.java (.../ActivityURL.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -38,6 +38,7 @@ private String title; private String description; private boolean complete; + private boolean defaultURL; public ActivityURL(){} @@ -78,4 +79,12 @@ public void setDescription(String description) { this.description = description; } + + public boolean isDefaultURL() { + return defaultURL; + } + + public void setDefaultURL(boolean defaultURL) { + this.defaultURL = defaultURL; + } } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java =================================================================== diff -u -r5863520d75343b47f77b05ad3bd7045a9a39af49 -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java (.../LearningWebUtil.java) (revision 5863520d75343b47f77b05ad3bd7045a9a39af49) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/util/LearningWebUtil.java (.../LearningWebUtil.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -33,10 +33,12 @@ import org.apache.log4j.Logger; import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; import org.lamsfoundation.lams.learning.service.ICoreLearnerService; import org.lamsfoundation.lams.learning.service.LearnerServiceException; import org.lamsfoundation.lams.learning.web.action.ActivityAction; +import org.lamsfoundation.lams.learning.web.bean.ActivityURL; import org.lamsfoundation.lams.learning.web.form.ActivityForm; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.LearningDesign; @@ -336,5 +338,17 @@ return progressSummary.toString(); } - + public static ActivityURL getActivityURL( ActivityMapping activityMapping, LearnerProgress learnerProgress, Activity activity, boolean defaultURL) { + ActivityURL activityURL = new ActivityURL(); + String url = activityMapping.getActivityURL(activity); + activityURL.setUrl(url); + activityURL.setActivityId(activity.getActivityId()); + activityURL.setTitle(activity.getTitle()); + activityURL.setDescription(activity.getDescription()); + if (learnerProgress.getProgressState(activity) == LearnerProgress.ACTIVITY_COMPLETED) { + activityURL.setComplete(true); + } + activityURL.setDefaultURL(defaultURL); + return activityURL; + } } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -re1683b7e5ac777deb10d15b0bf41182587ca8373 -r560c00149837e66be2b9f4cbcbff95ff23a4dc28 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision e1683b7e5ac777deb10d15b0bf41182587ca8373) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 560c00149837e66be2b9f4cbcbff95ff23a4dc28) @@ -2026,12 +2026,7 @@ grouping = branchingActivity.getGrouping(); group = lessonService.createGroup(grouping, branch.getTitle()); - - GroupBranchActivityEntry entry = new GroupBranchActivityEntry(null, null, group, branch, (BranchingActivity) branchingActivity); - if ( group.getBranchActivities() == null ) { - group.setBranchActivities(new HashSet()); - } - group.getBranchActivities().add(entry); + group.allocateBranchToGroup(null,null, branch, (BranchingActivity)branchingActivity); groupingDAO.update(group); } else {