Index: lams_learning/lib/lams/lams.jar =================================================================== diff -u -r09b65e403c9fcb6cc894e6af85c408e654b46f8c -r58a3a69656b21b5047527feab5777a6b9d5b2320 Binary files differ Index: lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java =================================================================== diff -u -r09b65e403c9fcb6cc894e6af85c408e654b46f8c -r58a3a69656b21b5047527feab5777a6b9d5b2320 --- lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java (.../ProgressEngine.java) (revision 09b65e403c9fcb6cc894e6af85c408e654b46f8c) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java (.../ProgressEngine.java) (revision 58a3a69656b21b5047527feab5777a6b9d5b2320) @@ -1,27 +1,26 @@ /* -Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA -http://www.gnu.org/licenses/gpl.txt -*/ + http://www.gnu.org/licenses/gpl.txt + */ package org.lamsfoundation.lams.learning.progress; - import org.lamsfoundation.lams.learningdesign.*; import org.lamsfoundation.lams.lesson.*; import org.lamsfoundation.lams.usermanagement.User; @@ -30,82 +29,127 @@ * The Progress Engine controls how a learner progresses * through a sequence. * - * @author chris + * @author chris, Jacky */ public class ProgressEngine { - + /** - * Creates a new instance of ProgressEngine. - */ - public ProgressEngine() - { - } - - /** * Method determines next step for a learner based on the activity * they have just completed. * @param learner The User who is progressing through the Lesson. * @param completedActivity The Activity the learner has just completed. * @param lesson The Lesson the learner needs progress for. + * @param learnerProgress * @return Progress The VO that contains the data needed to send * the learner to the next step. * @throws ProgressException if progress cannot be calculated successfully. */ - public LearnerProgress calculateProgress(User learner, - Lesson lesson, + public LearnerProgress calculateProgress(User learner, + Lesson lesson, Activity completedActivity, LearnerProgress learnerProgress) throws ProgressException { - learnerProgress.setProgressState(completedActivity,LearnerProgress.ACTIVITY_COMPLETED); + learnerProgress.setProgressState(completedActivity, + LearnerProgress.ACTIVITY_COMPLETED); + + Transition transition = completedActivity.getTransitionFrom(); + + if (transition != null) + return progressCompletedActivity(completedActivity, + learnerProgress, + transition); + else + return progressParentActivity(learner, + lesson, + completedActivity, + learnerProgress); + } + + /** + * 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. + * @throws ProgressException if the start point cannot be calculated successfully. + */ + public void setUpStartPoint(User learner, Lesson lesson, + LearnerProgress progress) throws ProgressException + { - Transition transition = completedActivity.getTransitionTo(); + LearningDesign ld = lesson.getLearningDesign(); - if(transition !=null) - return progressCompletedActivity(completedActivity, learnerProgress, transition); - else - { - Activity parent = completedActivity.getParentActivity(); - //if(parent!=null) - - - } - return null; + 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()); + progress.setProgressState(ld.getFirstActivity(),LearnerProgress.ACTIVITY_ATTEMPTED); } - /** + * * @param completedActivity * @param learnerProgress * @param transition * @return */ - private LearnerProgress progressCompletedActivity(Activity completedActivity, LearnerProgress learnerProgress, Transition transition) + private LearnerProgress progressCompletedActivity(Activity completedActivity, + LearnerProgress learnerProgress, + Transition transition) { learnerProgress.setPreviousActivity(completedActivity); - learnerProgress.setCurrentActivity(transition.getActivityByToActivityId()); - learnerProgress.setNextActivity(transition.getActivityByToActivityId()); - learnerProgress.setProgressState(transition.getActivityByToActivityId(), + learnerProgress.setCurrentActivity(transition.getToActivity()); + learnerProgress.setNextActivity(transition.getToActivity()); + learnerProgress.setProgressState(transition.getToActivity(), LearnerProgress.ACTIVITY_ATTEMPTED); return learnerProgress; } /** - * 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. - * @throws ProgressException if the start point cannot be calculated successfully. + * @param learner + * @param lesson + * @param completedActivity + * @param learnerProgress + * @return + * @throws ProgressException */ - public void setUpStartPoint(User learner, Lesson lesson, - LearnerProgress progress) throws ProgressException + private LearnerProgress progressParentActivity(User learner, + Lesson lesson, + Activity completedActivity, + LearnerProgress learnerProgress) throws ProgressException { - - LearningDesign ld = lesson.getLearningDesign(); - - progress.setCurrentActivity(ld.getFirstActivity()); - - progress.setNextActivity(ld.getFirstActivity()); - - progress.setProgressState(ld.getFirstActivity(),LearnerProgress.ACTIVITY_ATTEMPTED); + Activity parent = completedActivity.getParentActivity(); + if (parent != null) + { + //move to next activity within parent if not all children are completed. + if (!parent.areChildrenCompleted(learnerProgress)) + { + Activity nextActivity = parent.getNextActivityByParent(completedActivity); + + if (nextActivity.isNull()) + throw new ProgressException("Error occurred in progress engine." + + " Unexpected Null activity received when progressing" + + " to the next activity within a incomplete parent activity:" + + " Parent activity id [" + + parent.getActivityId() + + "]"); + + learnerProgress.setNextActivity(nextActivity); + learnerProgress.setProgressState(nextActivity, + LearnerProgress.ACTIVITY_ATTEMPTED); + } + //recurvisely call back to calculateProgress to calculate completed + //parent activity. + else + calculateProgress(learner, lesson, parent, learnerProgress); + } + //lesson is meant to be completed if there is no transition and no parent. + else + learnerProgress.setLessonComplete(true); + + return learnerProgress; } - -} + +} \ No newline at end of file Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java =================================================================== diff -u -r09b65e403c9fcb6cc894e6af85c408e654b46f8c -r58a3a69656b21b5047527feab5777a6b9d5b2320 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision 09b65e403c9fcb6cc894e6af85c408e654b46f8c) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision 58a3a69656b21b5047527feab5777a6b9d5b2320) @@ -184,7 +184,11 @@ { LearnerProgress learnerProgress = learnerProgressDAO.getLearnerProgressByLearner(learner,lesson); - return progressEngine.calculateProgress(learner, lesson, completedActivity,learnerProgress); + learnerProgress = progressEngine.calculateProgress(learner, lesson, completedActivity,learnerProgress); + + learnerProgressDAO.updateLearnerProgress(learnerProgress); + + return learnerProgress; } Index: lams_learning/test/java/WEB-INF/spring/learningApplicationContext.xml =================================================================== diff -u -rf73c3d7878d6f6c013a43da96353e4e0983e1a61 -r58a3a69656b21b5047527feab5777a6b9d5b2320 --- lams_learning/test/java/WEB-INF/spring/learningApplicationContext.xml (.../learningApplicationContext.xml) (revision f73c3d7878d6f6c013a43da96353e4e0983e1a61) +++ lams_learning/test/java/WEB-INF/spring/learningApplicationContext.xml (.../learningApplicationContext.xml) (revision 58a3a69656b21b5047527feab5777a6b9d5b2320) @@ -27,6 +27,7 @@ PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED + PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED Index: lams_learning/test/java/org/lamsfoundation/lams/learning/service/TestLearnerService.java =================================================================== diff -u -r09b65e403c9fcb6cc894e6af85c408e654b46f8c -r58a3a69656b21b5047527feab5777a6b9d5b2320 --- lams_learning/test/java/org/lamsfoundation/lams/learning/service/TestLearnerService.java (.../TestLearnerService.java) (revision 09b65e403c9fcb6cc894e6af85c408e654b46f8c) +++ lams_learning/test/java/org/lamsfoundation/lams/learning/service/TestLearnerService.java (.../TestLearnerService.java) (revision 58a3a69656b21b5047527feab5777a6b9d5b2320) @@ -23,6 +23,9 @@ import org.lamsfoundation.lams.AbstractLamsTestCase; import org.lamsfoundation.lams.learning.progress.ProgressException; +import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.OptionsActivity; +import org.lamsfoundation.lams.learningdesign.ParallelActivity; import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; @@ -56,7 +59,17 @@ //--------------------------------------------------------------------- private User testUser; private Lesson testLesson; - private LearnerProgress testProgress; + private static LearnerProgress testProgress; + private static final long TEST_NB_ACTIVITY_ID = 15; + private static final long TEST_RGRP_ACTIVITY_ID = 23; + private static final long TEST_CHAT_ACTIVITY_ID = 21; + private static final long TEST_QNA_ACTIVITY_ID = 24; + private static final long TEST_OPTIONS_ACTIVITY_ID = 12; + private static final long TEST_CNB_ACTIVITY_ID = 16; + private static final long TEST_Parallel_ACTIVITY_ID = 13; + private static final long TEST_CQNA_ACTIVITY_ID = 18; + private static final long TEST_WAITING_ACTIVITY_ID = 0; + /* * @see TestCase#setUp() */ @@ -117,4 +130,81 @@ ((ToolActivity)testProgress.getNextActivity()).getToolSessions().size()); } + public void testCalculateProgress() throws ProgressException + { + //progress from survey to notice board + Activity testCompletedActivity = testProgress.getNextActivity(); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_NB_ACTIVITY_ID,TEST_NB_ACTIVITY_ID,1,"nb","nb"); + + //progress from notice board to random grouping activity + testCompletedActivity = testProgress.getNextActivity(); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_RGRP_ACTIVITY_ID,TEST_RGRP_ACTIVITY_ID,2,"random grouping","random grouping"); + + //progress from random grouping activity to chat + testCompletedActivity = testProgress.getNextActivity(); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_CHAT_ACTIVITY_ID,TEST_CHAT_ACTIVITY_ID,3,"chat","chat"); + + //progress from chat to QNA + testCompletedActivity = testProgress.getNextActivity(); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_QNA_ACTIVITY_ID,TEST_QNA_ACTIVITY_ID,4,"QNA","QNA"); + + //progress from QNA to options activity + testCompletedActivity = testProgress.getNextActivity(); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_OPTIONS_ACTIVITY_ID,TEST_OPTIONS_ACTIVITY_ID,5,"OPTIONS","OPTIONS"); + + //progress from sub option(notice board) to parallel activity + testCompletedActivity = ((OptionsActivity)testProgress.getCurrentActivity()).getChildActivityById(TEST_CNB_ACTIVITY_ID); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity.getParentActivity(),TEST_Parallel_ACTIVITY_ID,TEST_Parallel_ACTIVITY_ID,7,"PARALLEL","PARALLEL"); + + //progress from sub parallel(QNA) to waiting +/** testCompletedActivity = ((ParallelActivity)testProgress.getCurrentActivity()).getChildActivityById(TEST_CQNA_ACTIVITY_ID); + testProgress = learnerService.calculateProgress(testCompletedActivity, + testUser, + testLesson); + assertLearnerProgress(testCompletedActivity,TEST_Parallel_ACTIVITY_ID,TEST_WAITING_ACTIVITY_ID,7,"PARALLEL","WAITING"); + +*/ + } + + /** + * @param testCompletedActivity + */ + private void assertLearnerProgress(Activity testCompletedActivity, + long curActivityId, + long nextActivityId, + int numberOfCompletedActivities, + String currentAct, + String nextAct) + { + assertEquals("verify the expected previous activity", + testCompletedActivity.getActivityId(), + testProgress.getPreviousActivity().getActivityId()); + + assertEquals("verify the expected current activity - "+currentAct, + curActivityId, + testProgress.getCurrentActivity().getActivityId().longValue()); + assertEquals("verify the expected next activity - "+ nextAct, + nextActivityId, + testProgress.getNextActivity().getActivityId().longValue()); + assertEquals("verify the completed activities",numberOfCompletedActivities,testProgress.getCompletedActivities().size()); + assertEquals("verify the attempted activities",1,testProgress.getAttemptedActivities().size()); + } }