Index: lams_monitoring/build.xml =================================================================== diff -u -r99de97b7c8a1317e545cc8416655efec6fbbdf7c -r580e9bb194e76263d8a5ff2132d20dc1876010e8 --- lams_monitoring/build.xml (.../build.xml) (revision 99de97b7c8a1317e545cc8416655efec6fbbdf7c) +++ lams_monitoring/build.xml (.../build.xml) (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -137,6 +137,7 @@ + Index: lams_monitoring/conf/language/ApplicationResources.properties =================================================================== diff -u -r0d8523cc71b9c30f8a0e9f4fd25b23923302f254 -r580e9bb194e76263d8a5ff2132d20dc1876010e8 --- lams_monitoring/conf/language/ApplicationResources.properties (.../ApplicationResources.properties) (revision 0d8523cc71b9c30f8a0e9f4fd25b23923302f254) +++ lams_monitoring/conf/language/ApplicationResources.properties (.../ApplicationResources.properties) (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -1,5 +1,6 @@ # CVS ID: $Id$ # Language strings for the Monitoring classes and screens. Mostly error messages. +button.finished=Finished label.synch.gate.title=Synch Gate label.permission.gate.title=Permission Gate @@ -12,6 +13,27 @@ label.gate.closed=Closed label.gate.waiting.learners={0} out of {1} are waiting in front of the gate. +label.grouping.max.num.in.group.heading=Maximum number of groups: +label.grouping.general.instructions.heading=General Instructions: +label.grouping.general.instructions.line1=Place the lesson participants in their groups. Initially you can add and remove users, but once the grouping is used (that is, a participant starts an activity that uses the grouping) you will not be able to remove users from groups. If you try to remove someone from a group and they will not remove check their progress - if they start using the group while you are on this screen you will not get any errors but you will not be able to remove them from their group. You will still be able to add users to groups. +label.grouping.general.instructions.line2=To create a group, type a group name and click Add Group. Repeat as required. Select a group, then select students from Column 2 and click Add selected to group. Select students in Column 3 and click Remove selected members from group to remove them from the group membership. The changes are saved when you click any of the buttons. +label.grouping.group.heading=Groups +label.grouping.non.grouped.users.heading=Students without a Group +label.grouping.grouped.users.heading=Members of selected Group +label.grouping.no.groups.created=No groups have been created. +# Message displayed while the chosen grouping screen is getting data from the server +label.grouping.loading=( Loading... ) +# Error Message displayed if the server doesn't send data to the chosen grouping screen e.g. when getting list of users for a group. +error.grouping.data=Required Information not received from server. Error Code: +# Error Message displayed if the user clicks on the add group button (on chosen grouping) without typing in a group name. +error.grouping.add.group=Please enter a new group name to add. +# Error Message displayed if the user clicks on the remove group button (on chosen grouping) without selecting a group +error.grouping.remove.group=Please select a group to remove. +button.grouping.remove.selected.group=Remove selected group +button.grouping.add.group=Add group +button.grouping.add.user.to.group=Add selected to group +button.grouping.remove.user.from.group=Remove selected members + #Page title for monitoring screen monitor.title=Staff :: LAMS #Deleted Preview Message Screen Title (Debugging screen) Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java =================================================================== diff -u -r5176a39390628de74ff3c3ba5bab716164dbdb42 -r580e9bb194e76263d8a5ff2132d20dc1876010e8 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 5176a39390628de74ff3c3ba5bab716164dbdb42) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -27,15 +27,18 @@ import java.io.IOException; import java.util.Date; import java.util.List; +import java.util.SortedSet; import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ChosenGrouping; import org.lamsfoundation.lams.learningdesign.GateActivity; import org.lamsfoundation.lams.learningdesign.GroupingActivity; import org.lamsfoundation.lams.learningdesign.exception.LearningDesignProcessorException; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.service.LessonServiceException; import org.lamsfoundation.lams.tool.exception.LamsToolServiceException; import org.lamsfoundation.lams.usermanagement.Organisation; +import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.exception.UserAccessDeniedException; import org.lamsfoundation.lams.util.MessageService; @@ -356,9 +359,16 @@ * @param activityId id of the activity. * @return the requested activity object. */ - public Activity getActivityById(long activityId); + public Activity getActivityById(Long activityId); /** + * Return an activity object based on the requested id. + * @param activityId id of the activity. + * @return the requested activity object. + */ + public GroupingActivity getGroupingActivityById(Long activityID); + + /** * Returns the status of the gate in WDDX format. * * @param activityID The activity_id of the Activity whose gate must be checked @@ -427,8 +437,33 @@ */ public abstract int deleteAllOldPreviewLessons(); + /* ************ Supports the Chosen Groupings **********************************/ + public abstract SortedSet getClassMembersNotGrouped(Long lessonID, Long activityID); + /** Add a new group to a grouping activity. If name already exists or the name is blank, does not add a new group. + * @param activityID id of the grouping activity + * @param name group name + * @throws LessonServiceException + */ + public abstract void addGroup(Long activityID, String name) throws LessonServiceException; + + /** Remove a group to from a grouping activity. If the group does not exists then nothing happens. + * If the group is already used (e.g. a tool session exists) then it throws a LessonServiceException. + * @param activityID id of the grouping activity + * @param name group name + * @throws LessonServiceException + **/ + public abstract void removeGroup(Long activityID, Long groupID) throws LessonServiceException; + + /** Add learners to a group. Doesn't necessarily check if the user is already in another group. */ + public abstract void addUsersToGroup(Long activityID, Long groupID, String learnerIDs[]) throws LessonServiceException ; + + /** Remove a user to a group. If the user is not in the group, then nothing is changed. + * @throws LessonServiceException */ + public abstract void removeUsersFromGroup(Long activityID, Long groupID, String learnerIDs[]) throws LessonServiceException; + /* TODO Dummy methods - to be removed */ public List getLearningDesigns(Long userId); + } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -r5176a39390628de74ff3c3ba5bab716164dbdb42 -r580e9bb194e76263d8a5ff2132d20dc1876010e8 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 5176a39390628de74ff3c3ba5bab716164dbdb42) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -35,19 +35,23 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.SortedSet; import java.util.TreeMap; +import java.util.TreeSet; import java.util.Vector; import org.apache.log4j.Logger; import org.lamsfoundation.lams.authoring.service.IAuthoringService; import org.lamsfoundation.lams.learning.service.ILearnerService; import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ChosenGrouping; import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.GateActivity; import org.lamsfoundation.lams.learningdesign.Group; import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.GroupingActivity; import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.learningdesign.NullGroup; import org.lamsfoundation.lams.learningdesign.ScheduleGateActivity; import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; @@ -80,6 +84,7 @@ import org.lamsfoundation.lams.usermanagement.dao.IWorkspaceFolderDAO; import org.lamsfoundation.lams.usermanagement.exception.UserAccessDeniedException; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.usermanagement.util.LastNameAlphabeticComparator; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.MessageService; @@ -104,6 +109,8 @@ * because we need to load up tool's service dynamically according to the * selected learning design.

* + * TODO Analyse the efficiency of the grouping algorithms for adding/removing users. Possible performance issue. + * * @author Jacky Fang * @author Manpreet Minhas * @since 2/02/2005 @@ -945,14 +952,32 @@ } /** - * @see org.lamsfoundation.lams.monitoring.service.IMonitoringService#getActivityById(long) + * @see org.lamsfoundation.lams.monitoring.service.IMonitoringService#getActivityById(Long) */ - public Activity getActivityById(long activityId) + public Activity getActivityById(Long activityId) { - return activityDAO.getActivityByActivityId(new Long(activityId)); + return activityDAO.getActivityByActivityId(activityId); } /** + * @see org.lamsfoundation.lams.monitoring.service.IMonitoringService#getGroupingActivityById(Long) + */ + public GroupingActivity getGroupingActivityById(Long activityID) { + Activity activity = getActivityById(activityID); + if ( activity == null ) { + String error = "Activity missing. ActivityID was "+activityID; + log.error(error); + throw new MonitoringServiceException(error); + } else if ( ! activity.isGroupingActivity() ) { + String error = "Activity should have been GroupingActivity but was a different kind of activity. "+activity; + log.error(error); + throw new MonitoringServiceException(error); + } + + return (GroupingActivity) activity; + } + + /** * (non-Javadoc) * @see org.lamsfoundation.lams.monitoring.service.IMonitoringService#getAllContributeActivities(java.lang.Long) */ @@ -1184,7 +1209,7 @@ } log.debug("Performing grouping for " + groupName + "..."); - lessonService.performChosenGrouping(groupingActivity,learners); + lessonService.performGrouping(groupingActivity,groupName,learners); log.debug("Finish grouping for " + groupName); } @@ -1548,5 +1573,106 @@ return numDeleted; } - + + + /* ************** Grouping related calls ***************************************/ + /** Get all the active learners in the lesson who are not in a group. + * + * TODO Optimise the database query. Do a single query rather then large collection access + * + * @param activityID + * @return Sorted set of Users, sorted by surname + */ + public SortedSet getClassMembersNotGrouped(Long lessonID, Long activityID) { + + GroupingActivity activity = getGroupingActivityById(activityID); + Grouping grouping = activity.getCreateGrouping(); + if ( grouping == null ) { + String error = "Grouping activity missing grouping. Activity was "+activity+" Grouping was "+grouping; + log.error(error); + throw new MonitoringServiceException(error); + } + + // get all the active learners + // then go through each group and remove the grouped users from the activeLearners set. + List activeLearners = lessonService.getActiveLessonLearners(lessonID); + if ( log.isDebugEnabled() ) { + log.debug("getClassMembersNotGrouped: Lesson "+lessonID+" has "+activeLearners.size()+" learners."); + } + + Iterator iter = grouping.getGroups().iterator(); + while ( iter.hasNext() ) { + Group group = (Group) iter.next(); + activeLearners.removeAll(group.getUsers()); + if ( log.isDebugEnabled() ) { + log.debug("getClassMembersNotGrouped: Group "+group.getGroupId()+" has "+group.getUsers().size()+" members."); + } + } + + if ( log.isDebugEnabled() ) { + log.debug("getClassMembersNotGrouped: Lesson "+lessonID+" has "+activeLearners.size()+" learners."); + } + + SortedSet sortedUsers = new TreeSet(new LastNameAlphabeticComparator()); + sortedUsers.addAll(activeLearners); + return sortedUsers; + } + + + /** Add a new group to a grouping activity. If name already exists or the name is blank, does not add a new group. + * @param activityID id of the grouping activity + * @param name group name + * @throws LessonServiceException + */ + public void addGroup(Long activityID, String name) throws LessonServiceException { + GroupingActivity groupingActivity = getGroupingActivityById(activityID); + lessonService.createGroup(groupingActivity, name); + } + + /** Remove a group to from a grouping activity. If the group does not exists then nothing happens. + * If the group is already used (e.g. a tool session exists) then it throws a LessonServiceException. + * @param activityID id of the grouping activity + * @param name group name + * @throws LessonServiceException + **/ + public void removeGroup(Long activityID, Long groupId) throws LessonServiceException { + GroupingActivity groupingActivity = getGroupingActivityById(activityID); + lessonService.removeGroup(groupingActivity, groupId); + } + + /** Add learners to a group. Doesn't necessarily check if the user is already in another group. */ + public void addUsersToGroup(Long activityID, Long groupId, String learnerIDs[]) throws LessonServiceException { + + GroupingActivity groupingActivity = getGroupingActivityById(activityID); + ArrayList learners = createUserList(activityID, learnerIDs,"add"); + lessonService.performGrouping(groupingActivity, groupId, learners); + } + + private ArrayList createUserList(Long activityID, String[] learnerIDs, String addRemoveText) { + ArrayList learners = new ArrayList(); + for ( String strlearnerID: learnerIDs ) { + boolean added = false; + try { + Integer learnerID = new Integer(Integer.parseInt(strlearnerID)); + User learner = userManagementService.getUserById(learnerID); + if ( learner != null ) { + learners.add(learner); + added = true; + } + } catch ( NumberFormatException e ) { } + if ( ! added ) { + log.warn("Unable to "+addRemoveText+" learner "+strlearnerID+" for group in grouping activity "+activityID+" as learner cannot be found."); + } + } + return learners; + } + + /** Remove a user to a group. If the user is not in the group, then nothing is changed. + * @throws LessonServiceException */ + public void removeUsersFromGroup(Long activityID, Long groupId, String learnerIDs[]) throws LessonServiceException { + + GroupingActivity groupingActivity = getGroupingActivityById(activityID); + ArrayList learners = createUserList(activityID, learnerIDs,"remove"); + lessonService.removeLearnersFromGroup(groupingActivity, groupId, learners); + } } \ No newline at end of file Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java =================================================================== diff -u --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java (revision 0) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/GroupingAJAXAction.java (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -0,0 +1,390 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * 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 + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.monitoring.web; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.struts.action.ActionForm; +import org.apache.struts.action.ActionForward; +import org.apache.struts.action.ActionMapping; +import org.lamsfoundation.lams.learning.service.ILearnerService; +import org.lamsfoundation.lams.learning.service.LearnerServiceProxy; +import org.lamsfoundation.lams.learning.web.util.LearningWebUtil; +import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ChosenGrouping; +import org.lamsfoundation.lams.learningdesign.Group; +import org.lamsfoundation.lams.learningdesign.GroupComparator; +import org.lamsfoundation.lams.learningdesign.Grouping; +import org.lamsfoundation.lams.learningdesign.GroupingActivity; +import org.lamsfoundation.lams.lesson.service.LessonServiceException; +import org.lamsfoundation.lams.monitoring.service.IMonitoringService; +import org.lamsfoundation.lams.monitoring.service.MonitoringServiceException; +import org.lamsfoundation.lams.monitoring.service.MonitoringServiceProxy; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.usermanagement.util.LastNameAlphabeticComparator; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.action.LamsDispatchAction; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; + +/** +* The action servlet that provides the support for the +*
    +*
  • AJAX based Chosen Grouping screen
  • +*
  • forwards to the learner's view grouping screen for Random Grouping.
  • +*
+* +* @author Fiona Malikoff + +* ----------------XDoclet Tags-------------------- +* +* @struts:action path="/grouping" +* parameter="method" +* validate="false" +* @struts.action-exception key="error.system.monitor" scope="request" +* type="org.lamsfoundation.lams.monitoring.service.MonitoringServiceException" +* path=".systemError" +* handler="org.lamsfoundation.lams.web.util.CustomStrutsExceptionHandler" +* @struts.action-exception key="error.system.monitor" scope="request" +* type="org.lamsfoundation.lams.lesson.service.LessonServiceException" +* path=".systemError" +* handler="org.lamsfoundation.lams.web.util.CustomStrutsExceptionHandler" +* @struts.action-forward name = "chosenGrouping" path = "/grouping/chosenGrouping.jsp" +* @struts.action-forward name = "viewGroups" path = ".viewGroups" +* +* ----------------XDoclet Tags-------------------- +*/ +public class GroupingAJAXAction extends LamsDispatchAction { + + //--------------------------------------------------------------------- + + private static final String CHOSEN_GROUPING_SCREEN = "chosenGrouping"; + private static final String VIEW_GROUPS_SCREEN = "viewGroups"; + private static final String PARAM_ACTIVITY_TITLE = "title"; + private static final String PARAM_ACTIVITY_DESCRIPTION = "description"; + public static final String PARAM_MAX_NUM_GROUPS = "maxNumberOfGroups"; + public static final String PARAM_NAME = "name"; + public static final String PARAM_GROUPS = "groups"; + public static final String PARAM_MEMBERS = "members"; + public static final String PARAM_MAY_DELETE = "mayDelete"; + + private Integer getUserId(HttpServletRequest request) { + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + return user != null ? user.getUserID() : null; + } + + + private void writeAJAXResponse(HttpServletResponse response, String output) throws IOException { + response.setContentType("text/html"); + PrintWriter writer = response.getWriter(); + // set it to unicode + if (output.length()>0) { + writer.println(output); + } + } + + private void writeAJAXOKResponse(HttpServletResponse response) throws IOException { + writeAJAXResponse(response, "OK"); + } + + private Grouping getGrouping(GroupingActivity activity) { + Grouping grouping = activity.getCreateGrouping(); + if ( grouping == null ) { + String error = "Grouping activity missing grouping. Activity was "+activity+" Grouping was "+grouping; + log.error(error); + throw new MonitoringServiceException(error); + } + return grouping; + } + + /** + * Start the process of doing the chosen grouping + * + * Input parameters: activityID + */ + public ActionForward startGrouping(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long lessonId = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + GroupingActivity activity = monitoringService.getGroupingActivityById(activityID); + Grouping grouping = activity.getCreateGrouping(); + if ( grouping == null ) { + String error = "Grouping activity missing grouping. Activity was "+activity; + log.error(error); + throw new MonitoringServiceException(error); + } + + request.setAttribute(AttributeNames.PARAM_ACTIVITY_ID, activityID); + request.setAttribute(AttributeNames.PARAM_LESSON_ID, lessonId); + request.setAttribute(PARAM_ACTIVITY_TITLE, activity.getTitle()); + request.setAttribute(PARAM_ACTIVITY_DESCRIPTION, activity.getDescription()); + + if ( grouping.isChosenGrouping() ) { + request.setAttribute(PARAM_MAX_NUM_GROUPS, grouping.getMaxNumberOfGroups()); + // can I remove groups/users - can't if tool sessions have been created + Set groups = grouping.getGroups(); + Iterator iter = groups.iterator(); + boolean mayDelete = true; + while (mayDelete && iter.hasNext()) { + Group group = (Group) iter.next(); + mayDelete = group.mayBeDeleted(); + } + request.setAttribute(PARAM_MAY_DELETE, mayDelete); + return mapping.findForward(CHOSEN_GROUPING_SCREEN); + + } else { + + // go to a view only screen for random grouping + SortedSet groups = new TreeSet(new GroupComparator()); + groups.addAll(grouping.getGroups()); + request.getSession().setAttribute(PARAM_GROUPS,groups); + return mapping.findForward(VIEW_GROUPS_SCREEN); + } + + } + + /** + * Get a list of group names and the number of users in each group. Designed to respond to an AJAX call. + * + * Input parameters: activityID + * + * Output format: "groupid,name,num users;groupid,name,num users" + */ + public ActionForward getGroups(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + // get the grouping data and sort it. + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + GroupingActivity activity = monitoringService.getGroupingActivityById(activityID); + Grouping grouping = getGrouping(activity); + Set sortedGroups = new TreeSet(new GroupComparator()); + sortedGroups.addAll(grouping.getGroups()); + + // build the output string to return to the chosen grouping page. + String groupOutput = ""; + boolean first = true; + for ( Group group: sortedGroups ) { + Long groupId = group.getGroupId(); + String name = group.getGroupName(); + Integer numberOfMembers = group.getUsers().size(); + if ( ! first ) { + groupOutput=groupOutput+";"; + } else { + first = false; + } + groupOutput=groupOutput+groupId+","+name+","+numberOfMembers; + } + writeAJAXResponse(response, groupOutput); + return null; + } + + /** + * Get a list of all the class members who aren't grouped yet. Designed to respond to an AJAX call. + * + * Input parameters: activityID + * + * Output format: "groupid,name,num users;groupid,name,num users" + */ + public ActionForward getClassMembersNotGrouped(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + // get the grouping data and sort it. + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long lessonID = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + SortedSet users = monitoringService.getClassMembersNotGrouped(lessonID, activityID); + String groupOutput = buildUserString(users); + writeAJAXResponse(response, groupOutput); + return null; + + } + + /** + * Get a list of group names and the number of users in each group. Designed to respond to an AJAX call. + * + * Input parameters: activityID, groupID + * + * Output format: "userid,lastname,firstname;" + */ + public ActionForward getGroupMembers(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + + // TODO optimise this call - we don't really need the activity and the grouping - go straight to the group in the db + // get the group, and from there the user data and sort the user data. + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long groupID = WebUtil.readLongParam(request, AttributeNames.PARAM_GROUP_ID); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + GroupingActivity activity = monitoringService.getGroupingActivityById(activityID); + Grouping grouping = getGrouping(activity); + Set groups = grouping.getGroups(); + Iterator iter = groups.iterator(); + Group group = null; + while (group==null && iter.hasNext()) { + Group candidateGroup = (Group) iter.next(); + if ( groupID.equals(candidateGroup.getGroupId()) ) + group = candidateGroup; + } + if ( group == null ) { + String error = "Group cannot be found. Activity was "+activity+" Grouping was "+grouping+" Grouping ID was "+groupID; + log.error(error); + throw new MonitoringServiceException(error); + } + + Set users = group.getUsers(); + SortedSet sortedUsers = new TreeSet(new LastNameAlphabeticComparator()); + sortedUsers.addAll(users); + String userOutput = buildUserString(sortedUsers); + writeAJAXResponse(response, userOutput); + return null; + } + + + /** + * Output format: "userid,lastname,firstname;" + * @param sortedUsers + * @return String of users + */ + private String buildUserString(SortedSet sortedUsers) { + String userOutput = ""; + boolean first = true; + for ( User user : sortedUsers ) { + Integer userID = user.getUserId(); + String lastName = user.getLastName(); + String firstName = user.getFirstName(); + if ( ! first ) { + userOutput=userOutput+";"; + } else { + first = false; + } + userOutput=userOutput+userID+","+lastName+","+firstName; + } + return userOutput; + } + + /** + * Add a new group. Designed to respond to an AJAX call. + * + * Input parameters: activityID, name (group name) + * + * Output format: no data returned - just the header + */ + public ActionForward addGroup(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException, LessonServiceException { + + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + String name = WebUtil.readStrParam(request, PARAM_NAME); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + monitoringService.addGroup(activityID, name); + writeAJAXResponse(response,""); + return null; + } + + /** + * Remove a group. Cannot remove the group if it is in use (tool session ids exist). Designed to respond to an AJAX call. + * + * Input parameters: activityID, name: group name + * + * Output format: no data returned - just the header + */ + public ActionForward removeGroup(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException, LessonServiceException { + + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long groupID = WebUtil.readLongParam(request, AttributeNames.PARAM_GROUP_ID); + + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + monitoringService.removeGroup(activityID, groupID); + writeAJAXOKResponse(response); + return null; + } + + /** + * Add learners to a group. Designed to respond to an AJAX call. + * + * Input parameters: activityID, name: group name, members: comma separated list of users + * + * Output format: no data returned - just the header + */ + public ActionForward addMembers(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException, LessonServiceException { + + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long groupID = WebUtil.readLongParam(request, AttributeNames.PARAM_GROUP_ID); + String members = WebUtil.readStrParam(request, PARAM_MEMBERS, true); + if ( members != null ) { + String[] membersSplit = members.split(","); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + monitoringService.addUsersToGroup(activityID, groupID, membersSplit); + } + writeAJAXOKResponse(response); + return null; + } + + /** + * Remove a list of users from a group. Designed to respond to an AJAX call. + * + * Input parameters: activityID, name: group name, members: comma separated list of users + * + * Output format: no data returned - just the header + */ + public ActionForward removeMembers(ActionMapping mapping, + ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException, LessonServiceException { + + Long activityID = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Long groupID = WebUtil.readLongParam(request, AttributeNames.PARAM_GROUP_ID); + String members = WebUtil.readStrParam(request, PARAM_MEMBERS, true); + if ( members != null ) { + String[] membersSplit = members.split(","); + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet().getServletContext()); + monitoringService.removeUsersFromGroup(activityID, groupID, membersSplit); + } + writeAJAXOKResponse(response); + return null; + } + +} Index: lams_monitoring/web/WEB-INF/struts/struts-config.xml =================================================================== diff -u -r0d064806d262c256111bd37392a61e856d83caee -r580e9bb194e76263d8a5ff2132d20dc1876010e8 --- lams_monitoring/web/WEB-INF/struts/struts-config.xml (.../struts-config.xml) (revision 0d064806d262c256111bd37392a61e856d83caee) +++ lams_monitoring/web/WEB-INF/struts/struts-config.xml (.../struts-config.xml) (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -42,6 +42,38 @@ + + + + + + + + + + + + \ No newline at end of file Index: lams_monitoring/web/grouping/chosenGrouping.jsp =================================================================== diff -u --- lams_monitoring/web/grouping/chosenGrouping.jsp (revision 0) +++ lams_monitoring/web/grouping/chosenGrouping.jsp (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -0,0 +1,460 @@ + <%-- +Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) +License Information: http://lamsfoundation.org/licensing/lams/2.0/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + 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 + + http://www.gnu.org/licenses/gpl.txt +--%> +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> + +<%@ taglib uri="tags-tiles" prefix="tiles" %> +<%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="tags-fmt" prefix="fmt" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + + + + + + + + <c:out value="${title}"/> + + + + + + + + + + + +
+ +

+ +

+ +

+

+ +

+ +

+ + + + + + + + + + + + +
+ +

+ " onclick="removeGroup()" disabled=true class="nav" /> +

+

+ + " onclick="addGroup()" class="nav" /> +

+
+ +

+ " onclick="addMembersToGroup()" disabled=true class="nav" /> +

+
+ +

+ " onclick="removeMembersFromGroup()" disabled=true class="nav" /> +

+
+ +
+ +
Index: lams_monitoring/web/grouping/viewGroups.jsp =================================================================== diff -u --- lams_monitoring/web/grouping/viewGroups.jsp (revision 0) +++ lams_monitoring/web/grouping/viewGroups.jsp (revision 580e9bb194e76263d8a5ff2132d20dc1876010e8) @@ -0,0 +1,65 @@ + <%-- +Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) +License Information: http://lamsfoundation.org/licensing/lams/2.0/ + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + 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 + + http://www.gnu.org/licenses/gpl.txt +--%> +<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %> + +<%@ taglib uri="tags-tiles" prefix="tiles" %> +<%@ taglib uri="tags-html" prefix="html" %> +<%@ taglib uri="tags-fmt" prefix="fmt" %> +<%@ taglib uri="tags-core" prefix="c" %> +<%@ taglib uri="tags-lams" prefix="lams" %> + + + + +

+ +

+ + + +

+
+ + + + + + + + +
+ + + + + + + + +
+ +
+
+
+
+ + + \ No newline at end of file