Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -r1c6cd416ca3946f49e0bb6cb2cecc7107887d7f5 -r052621201a47d79ee9f194dd86f78bbf84312893 Binary files differ Index: lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java =================================================================== diff -u -r95574f488cd396cd8e0e246a091a23dca4190e4f -r052621201a47d79ee9f194dd86f78bbf84312893 --- lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java (.../ILearnerProgressDAO.java) (revision 95574f488cd396cd8e0e246a091a23dca4190e4f) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java (.../ILearnerProgressDAO.java) (revision 052621201a47d79ee9f194dd86f78bbf84312893) @@ -24,6 +24,7 @@ package org.lamsfoundation.lams.lesson.dao; import java.util.List; +import java.util.Map; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.lesson.LearnerProgress; @@ -186,7 +187,7 @@ Integer getNumUsersCompletedLesson(Long lessonId); /** - * Get number of learners who are at the given activity at the moment. + * Get number of learners who are at the given activities at the moment. */ - Integer getNumUsersCurrentActivity(Activity activity); + Map getNumUsersCurrentActivities(Long[] activityIds); } Index: lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java =================================================================== diff -u -rb0f316ba255578b10b07a938baaf3afd4981f52e -r052621201a47d79ee9f194dd86f78bbf84312893 --- lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java (.../LearnerProgressDAO.java) (revision b0f316ba255578b10b07a938baaf3afd4981f52e) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java (.../LearnerProgressDAO.java) (revision 052621201a47d79ee9f194dd86f78bbf84312893) @@ -24,6 +24,8 @@ package org.lamsfoundation.lams.lesson.dao.hibernate; import java.util.List; +import java.util.Map; +import java.util.TreeMap; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -67,15 +69,15 @@ + " where p.lessonComplete > 0 and p.lesson.id = :lessonId"; private final static String COUNT_ATTEMPTED_ACTIVITY = "select count(*) from LearnerProgress prog, " - + " Activity act join prog.attemptedActivities attAct " + " where act.id = :activityId and " + + " Activity act join prog.attemptedActivities attAct where act.id = :activityId and " + " index(attAct) = act"; private final static String COUNT_COMPLETED_ACTIVITY = "select count(*) from LearnerProgress prog, " - + " Activity act join prog.completedActivities compAct " + " where act.id = :activityId and " + + " Activity act join prog.completedActivities compAct where act.id = :activityId and " + " index(compAct) = act"; - private final static String COUNT_CURRENT_ACTIVITY = "select count(*) from LearnerProgress prog WHERE " - + " prog.currentActivity = :activity"; + private final static String COUNT_CURRENT_ACTIVITY = "select prog.currentActivity.activityId, count(prog) " + + "from LearnerProgress prog WHERE prog.currentActivity.activityId IN (:activityIds) GROUP BY prog.currentActivity.activityId"; private final static String LOAD_PROGRESS_BY_LESSON = "from LearnerProgress p " + " where p.lesson.id = :lessonId order by p.user.lastName, p.user.firstName, p.user.userId"; @@ -423,15 +425,28 @@ }); } + @SuppressWarnings("unchecked") @Override - public Integer getNumUsersCurrentActivity(final Activity activity) { + public Map getNumUsersCurrentActivities(final Long[] activityIds) { HibernateTemplate hibernateTemplate = new HibernateTemplate(this.getSessionFactory()); - return (Integer) hibernateTemplate.execute(new HibernateCallback() { + return (Map) hibernateTemplate.execute(new HibernateCallback() { @Override public Object doInHibernate(Session session) throws HibernateException { - Object value = session.createQuery(LearnerProgressDAO.COUNT_CURRENT_ACTIVITY) - .setEntity("activity", activity).uniqueResult(); - return ((Number) value).intValue(); + List resultQuery = session.createQuery(LearnerProgressDAO.COUNT_CURRENT_ACTIVITY) + .setParameterList("activityIds", activityIds).list(); + Map result = new TreeMap(); + // put all requested activity IDs into the result + for (Long activityId : activityIds) { + result.put(activityId, 0); + } + // update only the existing ones + for (Object[] entry : resultQuery) { + // for some reason entry can be null + if (entry != null) { + result.put((Long) entry[0], ((Long) entry[1]).intValue()); + } + } + return result; } }); } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java =================================================================== diff -u -r9aad33f52b06632e7a8ed3705a7708338bcc00f8 -r052621201a47d79ee9f194dd86f78bbf84312893 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 9aad33f52b06632e7a8ed3705a7708338bcc00f8) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 052621201a47d79ee9f194dd86f78bbf84312893) @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.SortedSet; import org.lamsfoundation.lams.learningdesign.Activity; @@ -718,9 +719,9 @@ Integer getCountLearnersFromProgress(Long lessonId, String searchPhrase); /** - * Get number of learners who are at the given activity at the moment. + * Get number of learners who are at the given activities at the moment. */ - Integer getCountLearnersCurrentActivity(Activity activity); + Map getCountLearnersCurrentActivities(Long[] activityIds); /** * Get number of learners who finished the given lesson. Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -r9aad33f52b06632e7a8ed3705a7708338bcc00f8 -r052621201a47d79ee9f194dd86f78bbf84312893 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 9aad33f52b06632e7a8ed3705a7708338bcc00f8) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 052621201a47d79ee9f194dd86f78bbf84312893) @@ -956,7 +956,7 @@ // remove each Tool activity content // It has to be done before removing BranchEntries as fetching Tool content - // in its own transaction would re-add connected BranchEntries (Hibernate error) + // in its own transaction would re-add connected BranchEntries (Hibernate error) Set systemActivities = new HashSet(); for (Activity activity : (Set) learningDesign.getActivities()) { // get the real object, not the proxy @@ -965,7 +965,7 @@ ToolActivity toolActivity = (ToolActivity) activity; // delete content of each tool lamsCoreToolService.notifyToolToDeleteContent(toolActivity); - // possible nonthreadsafe access to session!!! + // possible nonthreadsafe access to session!!! lessonDAO.flush(); Long toolContentId = toolActivity.getToolContentId(); lessonDAO.deleteById(ToolContent.class, toolContentId); @@ -2457,8 +2457,8 @@ } @Override - public Integer getCountLearnersCurrentActivity(Activity activity) { - return learnerProgressDAO.getNumUsersCurrentActivity(activity); + public Map getCountLearnersCurrentActivities(Long[] activityIds) { + return learnerProgressDAO.getNumUsersCurrentActivities(activityIds); } @Override @@ -2482,10 +2482,10 @@ public int cloneLessons(String[] lessonIds, Boolean addAllStaff, Boolean addAllLearners, String[] staffIds, String[] learnerIds, Organisation group) throws MonitoringServiceException { int result = 0; - HttpSession ss = SessionManager.getSession(); - if (ss != null) { - UserDTO userDto = (UserDTO) ss.getAttribute(AttributeNames.USER); - if (userDto != null) { + HttpSession ss = SessionManager.getSession(); + if (ss != null) { + UserDTO userDto = (UserDTO) ss.getAttribute(AttributeNames.USER); + if (userDto != null) { Integer creatorId = userDto.getUserID(); for (String lessonIdStr : lessonIds) { @@ -2501,55 +2501,55 @@ return result; } - + @Override - public Long cloneLesson(Long lessonId, Integer creatorId, Boolean addAllStaff, Boolean addAllLearners, String[] staffIds, - String[] learnerIds, Organisation group) throws MonitoringServiceException { + public Long cloneLesson(Long lessonId, Integer creatorId, Boolean addAllStaff, Boolean addAllLearners, + String[] staffIds, String[] learnerIds, Organisation group) throws MonitoringServiceException { Lesson newLesson = null; - + securityService.isGroupMonitor(group.getOrganisationId(), creatorId, "cloneLesson", true); Lesson lesson = lessonService.getLesson(lessonId); if (lesson != null) { - if ((!addAllStaff && (staffIds.length > 0)) || addAllStaff) { - // create staff LessonClass - String staffGroupName = group.getName() + " Staff"; - List staffUsers = createStaffGroup(group.getOrganisationId(), addAllStaff, staffIds); + if ((!addAllStaff && (staffIds.length > 0)) || addAllStaff) { + // create staff LessonClass + String staffGroupName = group.getName() + " Staff"; + List staffUsers = createStaffGroup(group.getOrganisationId(), addAllStaff, staffIds); - if ((!addAllLearners && (learnerIds.length > 0)) || addAllLearners) { - // create learner LessonClass for lesson - String learnerGroupName = group.getName() + " Learners"; + if ((!addAllLearners && (learnerIds.length > 0)) || addAllLearners) { + // create learner LessonClass for lesson + String learnerGroupName = group.getName() + " Learners"; List learnerUsers = createLearnerGroup(group.getOrganisationId(), addAllLearners, learnerIds); - // init Lesson with user as creator - newLesson = this.initializeLesson(lesson.getLessonName(), lesson.getLessonDescription(), lesson - .getLearningDesign().getLearningDesignId(), group.getOrganisationId(), creatorId, null, - lesson.isEnableLessonIntro(), lesson.isDisplayDesignImage(), lesson - .getLearnerExportAvailable(), lesson.getLearnerPresenceAvailable(), lesson - .getLearnerImAvailable(), lesson.getLiveEditEnabled(), lesson - .getEnableLessonNotifications(), lesson.getLearnerRestart(), null, null); + // init Lesson with user as creator + newLesson = this.initializeLesson(lesson.getLessonName(), lesson.getLessonDescription(), + lesson.getLearningDesign().getLearningDesignId(), group.getOrganisationId(), creatorId, + null, lesson.isEnableLessonIntro(), lesson.isDisplayDesignImage(), + lesson.getLearnerExportAvailable(), lesson.getLearnerPresenceAvailable(), + lesson.getLearnerImAvailable(), lesson.getLiveEditEnabled(), + lesson.getEnableLessonNotifications(), lesson.getLearnerRestart(), null, null); - // save LessonClasses + // save LessonClasses newLesson = this.createLessonClassForLesson(newLesson.getLessonId(), group, learnerGroupName, learnerUsers, staffGroupName, staffUsers, creatorId); - // start Lessons - // TODO user-specified creator; must be someone in staff group - this.startLesson(newLesson.getLessonId(), staffUsers.get(0).getUserId()); + // start Lessons + // TODO user-specified creator; must be someone in staff group + this.startLesson(newLesson.getLessonId(), staffUsers.get(0).getUserId()); - } else { + } else { throw new MonitoringServiceException("No learners specified, can't create any Lessons."); - } - } else { - throw new MonitoringServiceException("No staff specified, can't create any Lessons."); - } - } else { + } + } else { + throw new MonitoringServiceException("No staff specified, can't create any Lessons."); + } + } else { throw new MonitoringServiceException("Couldn't find Lesson based on id=" + lessonId); - } + } return newLesson.getLessonId(); - } + } /* * Used in cloneLessons. Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java =================================================================== diff -u -r9aad33f52b06632e7a8ed3705a7708338bcc00f8 -r052621201a47d79ee9f194dd86f78bbf84312893 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 9aad33f52b06632e7a8ed3705a7708338bcc00f8) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 052621201a47d79ee9f194dd86f78bbf84312893) @@ -131,7 +131,6 @@ // --------------------------------------------------------------------- // Class level constants - Struts forward // --------------------------------------------------------------------- - private static final String PREVIEW_DELETED_REPORT_SCREEN = "previewdeleted"; private static final String NOT_SUPPORTED_SCREEN = "notsupported"; private static final String TIME_CHART_SCREEN = "timeChart"; private static final String ERROR = "error"; @@ -813,8 +812,8 @@ for (User learner : learners) { learnersJSON.put(WebUtil.userToJSON(learner)); } - - learnerCount = getMonitoringService().getCountLearnersCurrentActivity(activity); + learnerCount = getMonitoringService().getCountLearnersCurrentActivities(new Long[] { activityId }) + .get(activityId); } JSONObject responseJSON = new JSONObject(); @@ -1099,7 +1098,6 @@ JSONObject responseJSON = new JSONObject(); Lesson lesson = getLessonService().getLesson(lessonId); LearningDesign learningDesign = lesson.getLearningDesign(); - String contentFolderId = learningDesign.getContentFolderID(); Locale userLocale = new Locale(user.getLocaleLanguage(), user.getLocaleCountry()); @@ -1219,6 +1217,14 @@ responseJSON.put("searchedLearnerFound", searchedLearnerProgress != null); } + // Fetch number of learners at each activity + Long[] activityIds = new Long[activities.size()]; + int index = 0; + for (Activity activity : activities) { + activityIds[index++] = activity.getActivityId(); + } + Map learnerCounts = getMonitoringService().getCountLearnersCurrentActivities(activityIds); + JSONArray activitiesJSON = new JSONArray(); for (Activity activity : activities) { Long activityId = activity.getActivityId(); @@ -1264,25 +1270,18 @@ } // find few latest users and count of all users for each activity - int learnerCount = 0; + int learnerCount = learnerCounts.get(activityId); if (activity.isBranchingActivity() || activity.isOptionsWithSequencesActivity()) { // go through hidden children of complex activities and take them into account - learnerCount += getMonitoringService().getCountLearnersCurrentActivity(activity); Set children = parentToChildren.get(activityId); if (children != null) { for (Activity child : children) { - learnerCount += getMonitoringService().getCountLearnersCurrentActivity(child); + learnerCount += learnerCounts.get(child.getActivityId()); } } } else { List latestLearners = getMonitoringService().getLearnersLatestByActivity(activity.getActivityId(), MonitoringAction.LATEST_LEARNER_PROGRESS_ACTIVITY_DISPLAY_LIMIT, null); - if (latestLearners.size() < MonitoringAction.LATEST_LEARNER_PROGRESS_ACTIVITY_DISPLAY_LIMIT) { - // if there are less learners than the limit, we already know the size - learnerCount = latestLearners.size(); - } else { - learnerCount = getMonitoringService().getCountLearnersCurrentActivity(activity); - } if ((searchedLearnerProgress != null) && (searchedLearnerProgress.getCurrentActivity() != null) && activity.getActivityId() @@ -1390,7 +1389,6 @@ response.setContentType("application/json;charset=utf-8"); response.getWriter().print(responseJSON); return null; - } public ActionForward releaseGate(ActionMapping mapping, ActionForm form, HttpServletRequest request,