Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -r1fe0f4f546903187be6f35e4d5c027853da9408c -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 1fe0f4f546903187be6f35e4d5c027853da9408c) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -93,15 +93,12 @@ * @author Manpreet Minhas * @author Mailing Truong * - * This is a utility class for extracting the information from the WDDX packet - * sent by the FLASH. + * This is a utility class for extracting the information from the WDDX packet sent by the FLASH. * - * The following rules are applied: The client sends a subset of all possible - * data. If a field is included, then the value associated with this field - * should be persisted (the value maybe a new value or an unchanged value) If a - * field is not included then the server should assume that the value is - * unchanged. If the value of a field is one of the special null values, then - * null should be persisted. + * The following rules are applied: The client sends a subset of all possible data. If a field is included, then the + * value associated with this field should be persisted (the value maybe a new value or an unchanged value) If a field + * is not included then the server should assume that the value is unchanged. If the value of a field is one of the + * special null values, then null should be persisted. * * Object extractor has member data, so it should not be used as a singleton. * @@ -481,11 +478,10 @@ } /** - * Link SequenceActivities up with their firstActivity entries and - * BranchingActivities with their default branch. Also tidy up the order ids - * for sequence activities so that they are in the same order as the - * transitions - needed for the IMSLD export conversion to work. Not all the - * transitions may be drawn yet, so number off the others best we can. + * Link SequenceActivities up with their firstActivity entries and BranchingActivities with their default branch. + * Also tidy up the order ids for sequence activities so that they are in the same order as the transitions - needed + * for the IMSLD export conversion to work. Not all the transitions may be drawn yet, so number off the others best + * we can. * * @throws WDDXProcessorConversionException */ @@ -541,9 +537,8 @@ } /** - * Initialise the map of groupings with those in the db from a previous - * save. This must be called as soon as the learning design is read from the - * db and before it is changed. + * Initialise the map of groupings with those in the db from a previous save. This must be called as soon as the + * learning design is read from the db and before it is changed. */ private void initialiseGroupings() { List dbGroupings = groupingDAO.getGroupingsByLearningDesign(learningDesign.getLearningDesignId()); @@ -561,9 +556,8 @@ } /** - * Initialise the map of tool sessions already in the database. Used to work - * out what will be deleted by Hibernate later - useful to clean up any - * unwanted tool sessions for edit on the fly. + * Initialise the map of tool sessions already in the database. Used to work out what will be deleted by Hibernate + * later - useful to clean up any unwanted tool sessions for edit on the fly. */ @SuppressWarnings("unchecked") private void initialiseToolSessionMap(LearningDesign learningDesign) { @@ -588,12 +582,10 @@ } /** - * Delete the old tool session. Won't be done via Hibernate cascades as we - * only want to do it for edit on fly. The progress engine pre-generates the - * tool sessions for class level activities, so if we edit the design, we - * need to delete the tool sessions. If we encounter evidence that this is a - * grouped activity - either more than one tool session exists or the - * activity is grouped, then abort. + * Delete the old tool session. Won't be done via Hibernate cascades as we only want to do it for edit on fly. The + * progress engine pre-generates the tool sessions for class level activities, so if we edit the design, we need to + * delete the tool sessions. If we encounter evidence that this is a grouped activity - either more than one tool + * session exists or the activity is grouped, then abort. */ private void deleteUnwantedToolSessions(LearningDesign learningDesign) throws ObjectExtractorException { if (learningDesign.getEditOverrideLock() && learningDesign.getEditOverrideUser() != null) { @@ -639,10 +631,9 @@ } /** - * Parses the groupings array sent from the WDDX packet. It will create the - * groupings object (ChosenGrouping, RandomGrouping) so that when the - * GroupingActivity is processed, it can link to the grouping object that - * has been created by this method. + * Parses the groupings array sent from the WDDX packet. It will create the groupings object (ChosenGrouping, + * RandomGrouping) so that when the GroupingActivity is processed, it can link to the grouping object that has been + * created by this method. * * @param groupingsList * @throws WDDXProcessorConversionException @@ -822,12 +813,10 @@ } /** - * Parses the list of activities sent from the WDDX packet. The current - * activities that belong to this learning design will be compared with the - * new list of activities. Any new activities will be added to the database, - * existing activities will be updated, and any activities that are not - * present in the list of activities from the wddx packet (but appear in the - * list of current activities) are deleted. + * Parses the list of activities sent from the WDDX packet. The current activities that belong to this learning + * design will be compared with the new list of activities. Any new activities will be added to the database, + * existing activities will be updated, and any activities that are not present in the list of activities from the + * wddx packet (but appear in the list of current activities) are deleted. * * @param activitiesList * The list of activities from the WDDX packet. @@ -864,9 +853,8 @@ } /** - * Parses the list of activities sent from the WDDX packet for competence - * mappings. Each activity's new set of competenceMapping is compared - * against the old set and the db is updated accordingly + * Parses the list of activities sent from the WDDX packet for competence mappings. Each activity's new set of + * competenceMapping is compared against the old set and the db is updated accordingly * * @param activitiesList * The list of activities from the WDDX packet. @@ -973,12 +961,10 @@ } /** - * Parses the list of competences sent from the WDDX packet. The current - * competences that belong to this learning design will be compared with the - * new list of competences. Any new competences will be added to the - * database, existing competences will be updated, and any competences that - * are not present in the list of competences from the wddx packet (but - * appear in the list of current competences) are deleted. + * Parses the list of competences sent from the WDDX packet. The current competences that belong to this learning + * design will be compared with the new list of competences. Any new competences will be added to the database, + * existing competences will be updated, and any competences that are not present in the list of competences from + * the wddx packet (but appear in the list of current competences) are deleted. * * @param activitiesList * The list of activities from the WDDX packet. @@ -1048,10 +1034,9 @@ } /** - * Because the activities list was processed before by the method - * parseActivities, it is assumed that all activities have already been - * saved into the database. So now we can go through and find the any parent - * activity or input activities for an activity. + * Because the activities list was processed before by the method parseActivities, it is assumed that all activities + * have already been saved into the database. So now we can go through and find the any parent activity or input + * activities for an activity. * * @param activitiesList * @param learningDesign @@ -1117,9 +1102,8 @@ } /** - * Like parseActivities, parseTransitions parses the list of transitions - * from the wddx packet. New transitions will be added, existing transitions - * updated and any transitions that are no longer needed are deleted. + * Like parseActivities, parseTransitions parses the list of transitions from the wddx packet. New transitions will + * be added, existing transitions updated and any transitions that are no longer needed are deleted. * * @param transitionsList * The list of transitions from the wddx packet @@ -1335,22 +1319,23 @@ } else if (activity instanceof BranchingActivity) { buildBranchingActivity((BranchingActivity) activity, activityDetails); } else if (activity instanceof FloatingActivity) { - buildFloatingActivity((FloatingActivity) activity, activityDetails); - } else { + buildFloatingActivity((FloatingActivity) activity, activityDetails); + } else { buildSequenceActivity((SequenceActivity) activity, activityDetails); } } private void buildFloatingActivity(FloatingActivity floatingActivity, Hashtable activityDetails) - throws WDDXProcessorConversionException, ObjectExtractorException { - if (keyExists(activityDetails, WDDXTAGS.MAX_ACTIVITIES)) { - floatingActivity.setMaxNumberOfActivities(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.MAX_ACTIVITIES)); - } - - SystemTool systemTool = getSystemTool(SystemTool.FLOATING_ACTIVITIES); - floatingActivity.setSystemTool(systemTool); + throws WDDXProcessorConversionException, ObjectExtractorException { + if (keyExists(activityDetails, WDDXTAGS.MAX_ACTIVITIES)) { + floatingActivity.setMaxNumberOfActivities(WDDXProcessor.convertToInteger(activityDetails, + WDDXTAGS.MAX_ACTIVITIES)); + } + + SystemTool systemTool = getSystemTool(SystemTool.FLOATING_ACTIVITIES); + floatingActivity.setSystemTool(systemTool); } - + private void buildBranchingActivity(BranchingActivity branchingActivity, Hashtable activityDetails) throws WDDXProcessorConversionException, ObjectExtractorException { if (branchingActivity.isChosenBranchingActivity()) { @@ -1370,8 +1355,7 @@ private void buildGroupingActivity(GroupingActivity groupingActivity, Hashtable activityDetails) throws WDDXProcessorConversionException, ObjectExtractorException { /** - * read the createGroupingUUID, get the Grouping Object, and set - * CreateGrouping to that object + * read the createGroupingUUID, get the Grouping Object, and set CreateGrouping to that object */ Integer createGroupingUIID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.CREATE_GROUPING_UIID); Grouping grouping = groupings.get(createGroupingUIID); @@ -1488,15 +1472,13 @@ } /** - * Create the transition from a WDDX based hashtable. It is easier to go - * straight to the data object rather than going via the DTO, as the DTO - * returns the special null values from the getter methods. This makes it - * hard to set up the transaction object from the transitionDTO. + * Create the transition from a WDDX based hashtable. It is easier to go straight to the data object rather than + * going via the DTO, as the DTO returns the special null values from the getter methods. This makes it hard to set + * up the transaction object from the transitionDTO. *

- * Assumes that all the activities have been read and are in the - * newActivityMap. The toActivity and fromActivity are only set if the - * activity exists in the newActivityMap. If this leaves the transition with - * no to/from activities then null is returned. + * Assumes that all the activities have been read and are in the newActivityMap. The toActivity and fromActivity are + * only set if the activity exists in the newActivityMap. If this leaves the transition with no to/from activities + * then null is returned. * * @param transitionDetails * @throws WDDXProcessorConversionException @@ -1572,9 +1554,8 @@ } /** - * Wipe out any links fromany activities that may be linked to it (e.g. the - * case where a transition has an from activity but not a too activity. - * These cases should be picked up by Flash, but just in case. + * Wipe out any links fromany activities that may be linked to it (e.g. the case where a transition has an from + * activity but not a too activity. These cases should be picked up by Flash, but just in case. */ private void cleanupTransition(Transition transition) { if (transition.getFromActivity().getTransitionFrom().equals(transition)) { @@ -1586,15 +1567,12 @@ } /** - * Search in learning design for existing object. Can't go to database as - * that will trigger a Flush, and we haven't updated the rest of the design, - * so this would trigger a "deleted object would be re-saved by cascade" - * error. + * Search in learning design for existing object. Can't go to database as that will trigger a Flush, and we haven't + * updated the rest of the design, so this would trigger a "deleted object would be re-saved by cascade" error. * - * Check both the UUID for a match, and the to and from for a match. If the - * user deletes a transition then redraws it between the same activities, - * then inserting a new one in the db will trigger a duplicate key - * exception. So we need to reuse any that have the same to/from. + * Check both the UUID for a match, and the to and from for a match. If the user deletes a transition then redraws + * it between the same activities, then inserting a new one in the db will trigger a duplicate key exception. So we + * need to reuse any that have the same to/from. */ private Transition findTransition(Integer transitionUUID, Integer toUIID, Integer fromUIID) { Transition existingTransition = null; @@ -1613,9 +1591,8 @@ } /** - * Checks whether the hashtable contains the key specified by - * key If the key exists, returns true, otherwise return - * false. + * Checks whether the hashtable contains the key specified by key If the key exists, returns true, + * otherwise return false. * * @param table * The hashtable to check @@ -1640,11 +1617,10 @@ } /** - * Parses the mappings used for branching. They map groups to the sequence - * activities that form a branch within a branching activity. + * Parses the mappings used for branching. They map groups to the sequence activities that form a branch within a + * branching activity. * - * Must be done after all the other parsing as we need to match up - * activities and groups. + * Must be done after all the other parsing as we need to match up activities and groups. * * Will also delete any old (now unused) mappings * @@ -1686,8 +1662,8 @@ @SuppressWarnings("unchecked") /** - * Get the BranchActivityEntry details. This may be either for group based - * branching, or it may be for tool output based branching + * Get the BranchActivityEntry details. This may be either for group based branching, or it may be for tool output + * based branching */ private BranchActivityEntry extractBranchActivityEntry(Hashtable details) throws WDDXProcessorConversionException { @@ -1939,6 +1915,9 @@ learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(equalNumberOfLearnersPerGroup); } } + Boolean viewStudentsBeforeSelection = WDDXProcessor.convertToBoolean(groupingDetails, + WDDXTAGS.VIEW_STUDENTS_BEFORE_SELECTION); + learnerChoiceGrouping.setViewStudentsBeforeSelection(viewStudentsBeforeSelection); } private void buildConditionGateActivity(ConditionGateActivity activity, Hashtable activityDetails) Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Grouping.hbm.xml =================================================================== diff -u -r6cbd4eddf683da44fcbf3faed4ae3fe10e8336b8 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Grouping.hbm.xml (.../Grouping.hbm.xml) (revision 6cbd4eddf683da44fcbf3faed4ae3fe10e8336b8) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Grouping.hbm.xml (.../Grouping.hbm.xml) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -109,6 +109,11 @@ type="java.lang.Boolean" column="equal_number_of_learners_per_group" /> + Index: lams_common/db/sql/create_lams_11_tables.sql =================================================================== diff -u -rc697b5c30ab742ab453859355b35cd518856334f -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/db/sql/create_lams_11_tables.sql (.../create_lams_11_tables.sql) (revision c697b5c30ab742ab453859355b35cd518856334f) +++ lams_common/db/sql/create_lams_11_tables.sql (.../create_lams_11_tables.sql) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -400,6 +400,7 @@ , staff_group_id BIGINT(20) DEFAULT 0 , max_number_of_groups INT(3) , equal_number_of_learners_per_group TINYINT DEFAULT 0 + , view_students_before_selection TINYINT DEFAULT 0 , PRIMARY KEY (grouping_id) , INDEX (grouping_type_id) , CONSTRAINT FK_lams_learning_grouping_1 FOREIGN KEY (grouping_type_id) Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/LearnerChoiceGrouping.java =================================================================== diff -u -r6cbd4eddf683da44fcbf3faed4ae3fe10e8336b8 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/LearnerChoiceGrouping.java (.../LearnerChoiceGrouping.java) (revision 6cbd4eddf683da44fcbf3faed4ae3fe10e8336b8) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/LearnerChoiceGrouping.java (.../LearnerChoiceGrouping.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -27,74 +27,87 @@ /** * Grouping formed by learner's choice + * * @author Marcin Cieslak */ public class LearnerChoiceGrouping extends Grouping { - /** nullable persistent field */ - private Boolean equalNumberOfLearnersPerGroup; + /** nullable persistent field */ + private Boolean equalNumberOfLearnersPerGroup; - /** nullable persistent field */ - private Integer numberOfGroups; + /** nullable persistent field */ + private Integer numberOfGroups; - /** nullable persistent field */ - private Integer learnersPerGroup; + /** nullable persistent field */ + private Integer learnersPerGroup; - /** Creates a new instance of ChosenGrouping */ - public LearnerChoiceGrouping() { - super.grouper = new LearnerChoiceGrouper(); - } + /** nullable persistent field */ + private Boolean viewStudentsBeforeSelection; - /** full constructor */ - public LearnerChoiceGrouping(Long groupingId, Set groups, Set activities) { - super(groupingId, groups, activities, new LearnerChoiceGrouper()); - } + /** Creates a new instance of ChosenGrouping */ + public LearnerChoiceGrouping() { + super.grouper = new LearnerChoiceGrouper(); + } - /** - * This method creates a deep copy of the Grouping - * @return LearnerChoiceGrouping The deep copied Grouping object - */ - @Override - public Grouping createCopy(int uiidOffset) { - LearnerChoiceGrouping learnerChoiceGrouping = new LearnerChoiceGrouping(); - copyGroupingFields(learnerChoiceGrouping, uiidOffset); - learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(getEqualNumberOfLearnersPerGroup()); - learnerChoiceGrouping.setLearnersPerGroup(getLearnersPerGroup()); - learnerChoiceGrouping.setNumberOfGroups(getNumberOfGroups()); - return learnerChoiceGrouping; - } + /** full constructor */ + public LearnerChoiceGrouping(Long groupingId, Set groups, Set activities) { + super(groupingId, groups, activities, new LearnerChoiceGrouper()); + } - /** - * This type of grouping doesn't have groups other than learner groups. - * So it always return true. - * @see org.lamsfoundation.lams.learningdesign.Grouping#isLearnerGroup(org.lamsfoundation.lams.learningdesign.Group) - */ - @Override - public boolean isLearnerGroup(Group group) { - return true; - } + /** + * This method creates a deep copy of the Grouping + * + * @return LearnerChoiceGrouping The deep copied Grouping object + */ + @Override + public Grouping createCopy(int uiidOffset) { + LearnerChoiceGrouping learnerChoiceGrouping = new LearnerChoiceGrouping(); + copyGroupingFields(learnerChoiceGrouping, uiidOffset); + learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(getEqualNumberOfLearnersPerGroup()); + learnerChoiceGrouping.setLearnersPerGroup(getLearnersPerGroup()); + learnerChoiceGrouping.setNumberOfGroups(getNumberOfGroups()); + learnerChoiceGrouping.setViewStudentsBeforeSelection(getViewStudentsBeforeSelection()); + return learnerChoiceGrouping; + } - public Boolean getEqualNumberOfLearnersPerGroup() { - return equalNumberOfLearnersPerGroup; - } + /** + * This type of grouping doesn't have groups other than learner groups. So it always return true. + * + * @see org.lamsfoundation.lams.learningdesign.Grouping#isLearnerGroup(org.lamsfoundation.lams.learningdesign.Group) + */ + @Override + public boolean isLearnerGroup(Group group) { + return true; + } - public void setEqualNumberOfLearnersPerGroup(Boolean equalNumberOfLearnersPerGroup) { - this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; - } + public Boolean getEqualNumberOfLearnersPerGroup() { + return equalNumberOfLearnersPerGroup; + } - public Integer getLearnersPerGroup() { - return learnersPerGroup; - } + public void setEqualNumberOfLearnersPerGroup(Boolean equalNumberOfLearnersPerGroup) { + this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; + } - public void setLearnersPerGroup(Integer learnersPerGroup) { - this.learnersPerGroup = learnersPerGroup; - } + public Integer getLearnersPerGroup() { + return learnersPerGroup; + } - public Integer getNumberOfGroups() { - return numberOfGroups; - } + public void setLearnersPerGroup(Integer learnersPerGroup) { + this.learnersPerGroup = learnersPerGroup; + } - public void setNumberOfGroups(Integer numberOfGroups) { - this.numberOfGroups = numberOfGroups; - } + public Integer getNumberOfGroups() { + return numberOfGroups; + } -} + public void setNumberOfGroups(Integer numberOfGroups) { + this.numberOfGroups = numberOfGroups; + } + + public Boolean getViewStudentsBeforeSelection() { + return viewStudentsBeforeSelection; + } + + public void setViewStudentsBeforeSelection(Boolean viewStudentsBeforeSelection) { + this.viewStudentsBeforeSelection = viewStudentsBeforeSelection; + } +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/GroupingDTO.java =================================================================== diff -u -rd508da8b04374b653c2ea967ff2094bef7d4c199 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/GroupingDTO.java (.../GroupingDTO.java) (revision d508da8b04374b653c2ea967ff2094bef7d4c199) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/GroupingDTO.java (.../GroupingDTO.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -41,215 +41,232 @@ */ public class GroupingDTO extends BaseDTO { - private Long groupingID; - private Integer groupingUIID; - private Integer groupingTypeID; - private Integer numberOfGroups; - private Integer learnersPerGroup; - private Long staffGroupID; - private Integer maxNumberOfGroups; - private Boolean equalNumberOfLearnersPerGroup; - //list of GroupDTO - private List groups; + private Long groupingID; + private Integer groupingUIID; + private Integer groupingTypeID; + private Integer numberOfGroups; + private Integer learnersPerGroup; + private Long staffGroupID; + private Integer maxNumberOfGroups; + private Boolean equalNumberOfLearnersPerGroup; + private Boolean viewStudentsBeforeSelection; + // list of GroupDTO + private List groups; - public GroupingDTO(Long groupingID, Integer groupingUIID, Integer groupingType, Integer numberOfGroups, - Integer learnersPerGroup, Long staffGroupID, Integer maxNumberOfGroups, Boolean equalNumberOfLearnersPerGroup, - List groupDTOs) { - this.groupingID = groupingID; - this.groupingUIID = groupingUIID; - groupingTypeID = groupingType; - this.numberOfGroups = numberOfGroups; - this.learnersPerGroup = learnersPerGroup; - this.staffGroupID = staffGroupID; - this.maxNumberOfGroups = maxNumberOfGroups; - this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; - groups = groupDTOs; - } + public GroupingDTO(Long groupingID, Integer groupingUIID, Integer groupingType, Integer numberOfGroups, + Integer learnersPerGroup, Long staffGroupID, Integer maxNumberOfGroups, + Boolean equalNumberOfLearnersPerGroup, Boolean viewStudentsBeforeSelection, List groupDTOs) { + this.groupingID = groupingID; + this.groupingUIID = groupingUIID; + groupingTypeID = groupingType; + this.numberOfGroups = numberOfGroups; + this.learnersPerGroup = learnersPerGroup; + this.staffGroupID = staffGroupID; + this.maxNumberOfGroups = maxNumberOfGroups; + this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; + this.viewStudentsBeforeSelection = viewStudentsBeforeSelection; + groups = groupDTOs; + } - public GroupingDTO(Grouping grouping, boolean setupUserList) { - groupingID = grouping.getGroupingId(); - groupingUIID = grouping.getGroupingUIID(); - maxNumberOfGroups = grouping.getMaxNumberOfGroups(); - groupingTypeID = grouping.getGroupingTypeId(); - Set groupSet = grouping.getGroups(); - groups = new ArrayList(); - if (groupSet != null) { - Iterator iter = groupSet.iterator(); - while (iter.hasNext()) { - groups.add(((Group) iter.next()).getGroupDTO(setupUserList)); - } - } - /*The two lines of code below are commented out, because it creates a new grouping instance and then tries to - get the attributes for it , in which the values are null. So the grouping object is passed straight into - the processGroupingActivity() function. */ - //Object object = Grouping.getGroupingInstance(groupingTypeID); - //processGroupingActivity(object); - processGroupingActivity(grouping); + public GroupingDTO(Grouping grouping, boolean setupUserList) { + groupingID = grouping.getGroupingId(); + groupingUIID = grouping.getGroupingUIID(); + maxNumberOfGroups = grouping.getMaxNumberOfGroups(); + groupingTypeID = grouping.getGroupingTypeId(); + Set groupSet = grouping.getGroups(); + groups = new ArrayList(); + if (groupSet != null) { + Iterator iter = groupSet.iterator(); + while (iter.hasNext()) { + groups.add(((Group) iter.next()).getGroupDTO(setupUserList)); + } } + /* + * The two lines of code below are commented out, because it creates a new grouping instance and then tries to + * get the attributes for it , in which the values are null. So the grouping object is passed straight into the + * processGroupingActivity() function. + */ + // Object object = Grouping.getGroupingInstance(groupingTypeID); + // processGroupingActivity(object); + processGroupingActivity(grouping); + } - public void processGroupingActivity(Object object) { - if (object instanceof RandomGrouping) { - addRandomGroupingAttributes((RandomGrouping) object); - } - else if (object instanceof ChosenGrouping) { - addChosenGroupingAttributes((ChosenGrouping) object); - } - else if (object instanceof LearnerChoiceGrouping) { - addLearnerChoiceGroupingAttributes((LearnerChoiceGrouping) object); - } - else { - addLessonClassAttributes((LessonClass) object); - } + public void processGroupingActivity(Object object) { + if (object instanceof RandomGrouping) { + addRandomGroupingAttributes((RandomGrouping) object); + } else if (object instanceof ChosenGrouping) { + addChosenGroupingAttributes((ChosenGrouping) object); + } else if (object instanceof LearnerChoiceGrouping) { + addLearnerChoiceGroupingAttributes((LearnerChoiceGrouping) object); + } else { + addLessonClassAttributes((LessonClass) object); } + } - private void addRandomGroupingAttributes(RandomGrouping grouping) { - learnersPerGroup = grouping.getLearnersPerGroup(); - numberOfGroups = grouping.getNumberOfGroups(); - } + private void addRandomGroupingAttributes(RandomGrouping grouping) { + learnersPerGroup = grouping.getLearnersPerGroup(); + numberOfGroups = grouping.getNumberOfGroups(); + } - private void addChosenGroupingAttributes(ChosenGrouping grouping) { + private void addChosenGroupingAttributes(ChosenGrouping grouping) { - } + } - private void addLearnerChoiceGroupingAttributes(LearnerChoiceGrouping grouping) { - learnersPerGroup = grouping.getLearnersPerGroup(); - numberOfGroups = grouping.getNumberOfGroups(); - equalNumberOfLearnersPerGroup = grouping.getEqualNumberOfLearnersPerGroup(); - } + private void addLearnerChoiceGroupingAttributes(LearnerChoiceGrouping grouping) { + learnersPerGroup = grouping.getLearnersPerGroup(); + numberOfGroups = grouping.getNumberOfGroups(); + equalNumberOfLearnersPerGroup = grouping.getEqualNumberOfLearnersPerGroup(); + viewStudentsBeforeSelection = grouping.getViewStudentsBeforeSelection(); + } - private void addLessonClassAttributes(LessonClass grouping) { - staffGroupID = grouping.getStaffGroup().getGroupId(); - } + private void addLessonClassAttributes(LessonClass grouping) { + staffGroupID = grouping.getStaffGroup().getGroupId(); + } - /** - * @return Returns the groupingID. - */ - public Long getGroupingID() { - return groupingID; - } + /** + * @return Returns the groupingID. + */ + public Long getGroupingID() { + return groupingID; + } - /** - * @param groupingID The groupingID to set. - */ - public void setGroupingID(Long groupingID) { - if (!groupingID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_LONG)) { - this.groupingID = groupingID; - } + /** + * @param groupingID + * The groupingID to set. + */ + public void setGroupingID(Long groupingID) { + if (!groupingID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_LONG)) { + this.groupingID = groupingID; } + } - /** - * @return Returns the groupingType. - */ - public Integer getGroupingTypeID() { - return groupingTypeID; - } + /** + * @return Returns the groupingType. + */ + public Integer getGroupingTypeID() { + return groupingTypeID; + } - /** - * @param groupingType The groupingType to set. - */ - public void setGroupingTypeID(Integer groupingType) { - if (!groupingType.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { - groupingTypeID = groupingType; - } + /** + * @param groupingType + * The groupingType to set. + */ + public void setGroupingTypeID(Integer groupingType) { + if (!groupingType.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { + groupingTypeID = groupingType; } + } - /** - * @return Returns the groupingUIID. - */ - public Integer getGroupingUIID() { - return groupingUIID; - } + /** + * @return Returns the groupingUIID. + */ + public Integer getGroupingUIID() { + return groupingUIID; + } - /** - * @param groupingUIID The groupingUIID to set. - */ - public void setGroupingUIID(Integer groupingUIID) { - if (!groupingUIID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { - this.groupingUIID = groupingUIID; - } + /** + * @param groupingUIID + * The groupingUIID to set. + */ + public void setGroupingUIID(Integer groupingUIID) { + if (!groupingUIID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { + this.groupingUIID = groupingUIID; } + } - /** - * @return Returns the learnersPerGroup. - */ - public Integer getLearnersPerGroup() { - return learnersPerGroup; - } + /** + * @return Returns the learnersPerGroup. + */ + public Integer getLearnersPerGroup() { + return learnersPerGroup; + } - /** - * @param learnersPerGroup The learnersPerGroup to set. - */ - public void setLearnersPerGroup(Integer learnersPerGroup) { - if (!learnersPerGroup.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { - this.learnersPerGroup = learnersPerGroup; - } + /** + * @param learnersPerGroup + * The learnersPerGroup to set. + */ + public void setLearnersPerGroup(Integer learnersPerGroup) { + if (!learnersPerGroup.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { + this.learnersPerGroup = learnersPerGroup; } + } - /** - * @return Returns the maxNumberOfGroups. - */ - public Integer getMaxNumberOfGroups() { - return maxNumberOfGroups; - } + /** + * @return Returns the maxNumberOfGroups. + */ + public Integer getMaxNumberOfGroups() { + return maxNumberOfGroups; + } - /** - * @param maxNumberOfGroups The maxNumberOfGroups to set. - */ - public void setMaxNumberOfGroups(Integer maxNumberOfGroups) { - if (!maxNumberOfGroups.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { - this.maxNumberOfGroups = maxNumberOfGroups; - } + /** + * @param maxNumberOfGroups + * The maxNumberOfGroups to set. + */ + public void setMaxNumberOfGroups(Integer maxNumberOfGroups) { + if (!maxNumberOfGroups.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { + this.maxNumberOfGroups = maxNumberOfGroups; } + } - /** - * @return Returns the numberOfGroups. - */ - public Integer getNumberOfGroups() { - return numberOfGroups; - } + /** + * @return Returns the numberOfGroups. + */ + public Integer getNumberOfGroups() { + return numberOfGroups; + } - /** - * @param numberOfGroups The numberOfGroups to set. - */ - public void setNumberOfGroups(Integer numberOfGroups) { - if (!numberOfGroups.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { - this.numberOfGroups = numberOfGroups; - } + /** + * @param numberOfGroups + * The numberOfGroups to set. + */ + public void setNumberOfGroups(Integer numberOfGroups) { + if (!numberOfGroups.equals(WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)) { + this.numberOfGroups = numberOfGroups; } + } - /** - * @return Returns the staffGroupID. - */ - public Long getStaffGroupID() { - return staffGroupID; - } + /** + * @return Returns the staffGroupID. + */ + public Long getStaffGroupID() { + return staffGroupID; + } - /** - * @param staffGroupID The staffGroupID to set. - */ - public void setStaffGroupID(Long staffGroupID) { - if (!staffGroupID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_LONG)) { - this.staffGroupID = staffGroupID; - } + /** + * @param staffGroupID + * The staffGroupID to set. + */ + public void setStaffGroupID(Long staffGroupID) { + if (!staffGroupID.equals(WDDXTAGS.NUMERIC_NULL_VALUE_LONG)) { + this.staffGroupID = staffGroupID; } + } - /** - * - * @return group list belongs to this grouping. - */ - public List getGroups() { - return groups; - } + /** + * + * @return group list belongs to this grouping. + */ + public List getGroups() { + return groups; + } - public void setGroups(List groups) { - this.groups = groups; - } + public void setGroups(List groups) { + this.groups = groups; + } - public Boolean getEqualNumberOfLearnersPerGroup() { - return equalNumberOfLearnersPerGroup; - } + public Boolean getEqualNumberOfLearnersPerGroup() { + return equalNumberOfLearnersPerGroup; + } - public void setEqualNumberOfLearnersPerGroup(Boolean equalNumberOfLearnersPerGroup) { - this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; - } + public void setEqualNumberOfLearnersPerGroup(Boolean equalNumberOfLearnersPerGroup) { + this.equalNumberOfLearnersPerGroup = equalNumberOfLearnersPerGroup; + } + + public Boolean getViewStudentsBeforeSelection() { + return viewStudentsBeforeSelection; + } + + public void setViewStudentsBeforeSelection(Boolean viewStudentsBeforeSelection) { + this.viewStudentsBeforeSelection = viewStudentsBeforeSelection; + } } Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java =================================================================== diff -u -re3956ad12bff5c78c3708b9b6bb79a2ac515ee2c -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision e3956ad12bff5c78c3708b9b6bb79a2ac515ee2c) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -249,11 +249,11 @@ private static final String IMS_PREFIX_PROPERTY_REF = "P-"; // this is not IMS standard tag, temporarily use to gather all tools - // node list + // node list private static final String IMS_TAG_TRANSITIONS = "transitions"; // this is not IMS standard tag, term used to ref grouping/gate - // activities + // activities private static final String IMS_TAG_GROUPING = "group"; private static final String IMS_TAG_GATE = "gate"; @@ -311,9 +311,9 @@ private ApplicationContext applicationContext; // save list of all tool file node class information. One tool may have - // over one file node, such as + // over one file node, such as // in share resource tool, it has contnent attachment and shared - // resource item attachement. + // resource item attachement. private List fileHandleClassList; private Class filterClass; @@ -344,8 +344,7 @@ private static final String KEY_MSG_IMPORT_FILE_FORMAT = "msg.import.file.format"; /** - * Class of tool attachment file handler class and relative fields - * information container. + * Class of tool attachment file handler class and relative fields information container. */ private class NameInfo { @@ -463,7 +462,7 @@ // for import : unmarshal xml to object if (StringUtils.equals(method.getName(), "unmarshal") && result != null) { // During deserialize XML file into object, it will save - // file node into fileNodes + // file node into fileNodes for (NameInfo name : fileHandleClassList) { if (name.className.equals(result.getClass().getName())) { fileNodes.add(ExportToolContentService.this.new ValueInfo(name, result)); @@ -492,8 +491,8 @@ } /** - * This class is just for later system extent tool compaiblity strategy - * use. Currently, it just simple to get tool by same signature. + * This class is just for later system extent tool compaiblity strategy use. Currently, it just simple to get tool + * by same signature. * * @author Steve.Ni * @@ -525,13 +524,13 @@ FileUtil.createDirectory(contentDir); // this folder put all IMS XSLT transform temporary files, so - // try to keep content is clean for final + // try to keep content is clean for final // package! // The reason use temporary folder instead of delete temporary - // files from content folder is, sometimes, + // files from content folder is, sometimes, // delete file does not work well // this makes the final zip file should contain some rubbish - // files. + // files. String xsltTempDir = FileUtil.getFullPath(rootDir, ExportToolContentService.DIR_XSLT_TEMP); if (format == ExportToolContentService.PACKAGE_FORMAT_IMS) { FileUtil.createDirectory(xsltTempDir); @@ -546,7 +545,7 @@ Writer ldFile = new OutputStreamWriter(new FileOutputStream(ldFileName), "UTF-8"); // get learning desing and serialize it to XML file. Update the - // version to reflect the + // version to reflect the // version now, rather than the version when it was saved. ILearningDesignService service = getLearningDesignService(); LearningDesignDTO ldDto = service.getLearningDesignDTO(learningDesignId, ""); @@ -557,32 +556,31 @@ } /* - * learning design DTO is ready to be written into XML, but we - * need to find out which groupings and branching mappings are - * not supposed to be included into the structure (LDEV-1825) - */ + * learning design DTO is ready to be written into XML, but we need to find out which groupings and + * branching mappings are not supposed to be included into the structure (LDEV-1825) + */ Set groupingsToSkip = new TreeSet(); // for these branching activities there will be no branching - // mappings saved into XML, since they will be + // mappings saved into XML, since they will be // recreated in monitoring Set branchingActivitiesToSkip = new TreeSet(); // iterator all activities in this learning design and export - // their content to given folder. + // their content to given folder. // The content will contain tool.xml and attachment files of - // tools from LAMS repository. + // tools from LAMS repository. List activities = ldDto.getActivities(); // create resources Dom node list for IMS package. List resChildren = new ArrayList(); // iterator all activities and export tool.xml and its - // attachments + // attachments for (AuthoringActivityDTO activity : activities) { int activityTypeID = activity.getActivityTypeID().intValue(); // for teacher chosen and tool based branching activities there - // should be no groupings saved to XML + // should be no groupings saved to XML if (activityTypeID == Activity.CHOSEN_BRANCHING_ACTIVITY_TYPE || activityTypeID == Activity.TOOL_BRANCHING_ACTIVITY_TYPE) { Long groupingID = activity.getGroupingID(); @@ -595,7 +593,7 @@ continue; } // for group based define later branching activities there - // should be no branching mappings saved to XML + // should be no branching mappings saved to XML if (activityTypeID == Activity.GROUP_BRANCHING_ACTIVITY_TYPE && activity.getDefineLater()) { branchingActivitiesToSkip.add(activity.getActivityUIID()); } @@ -605,7 +603,7 @@ } // find out current acitivites toolContentMananger and export - // tool content. + // tool content. ToolContentManager contentManager = (ToolContentManager) findToolService(toolDAO.getToolByID(activity .getToolID())); log.debug("Tool export content : " + activity.getActivityTitle() + " by contentID :" @@ -616,7 +614,7 @@ String msg = activity.getToolDisplayName() + " export tool content failed:" + e.toString(); log.error(msg, e); // Try to delete tool.xml. This makes export_failed and - // tool.xml does not exist simultaneously. + // tool.xml does not exist simultaneously. String toolPath = FileUtil.getFullPath(contentDir, activity.getToolContentID().toString()); String toolFileName = FileUtil.getFullPath(toolPath, ExportToolContentService.TOOL_FILE_NAME); File toolFile = new File(toolFileName); @@ -634,7 +632,7 @@ } // end all activities export // skipping unwanted elements; learning design DTO is altered - // but not persisted; + // but not persisted; Iterator groupingIter = ldDto.getGroupings().iterator(); while (groupingIter.hasNext()) { if (groupingsToSkip.contains(groupingIter.next().getGroupingID())) { @@ -702,8 +700,8 @@ /** * Generate temporary files: resources.xml and transitions.xml.
- * Transform LAMS format learning_design.xml with resources.xml and - * transitions.xml into ims_learning_design.xml file. + * Transform LAMS format learning_design.xml with resources.xml and transitions.xml into ims_learning_design.xml + * file. * * @param resChildren * @param rootDir @@ -717,7 +715,7 @@ String ldFileName = FileUtil.getFullPath(xsltDir, ExportToolContentService.LEARNING_DESIGN_FILE_NAME); // copy XSLT file to contentDir, so that the XSLT document() function - // does not need absolute path file. + // does not need absolute path file. File xslt = new File(FileUtil.getFullPath(xsltDir, "ims.xslt")); FileUtil.copyFile(xsltIn, xslt); @@ -755,9 +753,9 @@ List sortedActList = getSortedActivities(ldDto); // Need to know what activities are branching activities, so we can set - // up conditions for their child sequences + // up conditions for their child sequences // Can't just do it for all sequences as the sequence could be in an - // optional activity + // optional activity Set branchingActivityIds = new HashSet(); for (AuthoringActivityDTO actDto : sortedActList) { if (actDto.getActivityTypeID().equals(Activity.CHOSEN_BRANCHING_ACTIVITY_TYPE) @@ -780,7 +778,7 @@ + "] into Transition tag."); // All sequence activities are within braching or an optional - // sequence, so they don't go into the transition + // sequence, so they don't go into the transition // list. if (actDto.getActivityTypeID().equals(Activity.SEQUENCE_ACTIVITY_TYPE)) { String attributeValue = ExportToolContentService.IMS_PREFIX_COMPLEX_REF @@ -795,7 +793,7 @@ } else if (actDto.getParentActivityID() == null) { // Only want to add it to the list of transition activities if - // it is the top level, as this generates + // it is the top level, as this generates // the initial sequence. Attribute att = null; @@ -847,7 +845,7 @@ + transFile.getAbsolutePath()); // create the properties file and conditions file - needed for gate - // showing gates when open and branches when + // showing gates when open and branches when // determined propertiesRoot.setChildren(propertiesChildren); propertiesDom.setRootElement(propertiesRoot); @@ -889,10 +887,9 @@ } /** - * Generate the nodes for a property and the related conditions. The - * first element is the property, which goes in the tag, - * the second through fourth elements are the if-then-else that makes up - * the condition and goes in the tag. + * Generate the nodes for a property and the related conditions. The first element is the property, which goes in + * the tag, the second through fourth elements are the if-then-else that makes up the condition and + * goes in the tag. * * @param activityId * @return @@ -948,15 +945,11 @@ } /** - * This quite complex method will return a sorted acitivityDTO list - * according to current LD DTO.
- * It considers the broken LD situation. A first activity will always be - * first one, but others in the broken sequence in this LD sorted by - * randomly. In one broken sequence, all activities will sorted by - * transition.
- * The reason to use lots "for" is Activity DTO does not contain next - * transition information. It has to be iterator all transitions or - * activities. + * This quite complex method will return a sorted acitivityDTO list according to current LD DTO.
+ * It considers the broken LD situation. A first activity will always be first one, but others in the broken + * sequence in this LD sorted by randomly. In one broken sequence, all activities will sorted by transition.
+ * The reason to use lots "for" is Activity DTO does not contain next transition information. It has to be iterator + * all transitions or activities. * * @param ldDto * @return @@ -970,7 +963,7 @@ HashMap activities = new HashMap(); // Put first activity into sorted list and copy the rest of the - // activities into a working map so we can find + // activities into a working map so we can find // them easily. // They can be removed from the map as we go so we don't reprocess them. Iterator iter = ldDto.getActivities().iterator(); @@ -1015,15 +1008,15 @@ } // already achieve one sequence end, but it still exist unsorted - // transition, it means + // transition, it means // this ld is broken one, there are at least two "first act" - // (there is no "transition to") + // (there is no "transition to") if (!find) { for (AuthoringActivityDTO act : activities.values()) { boolean isFirst = true; for (TransitionDTO tranDto : transList) { // there is some transition to this act, it is - // not "head activity" then skip this act. + // not "head activity" then skip this act. if (tranDto.getToActivityID().equals(act.getActivityID())) { isFirst = false; break; @@ -1047,18 +1040,17 @@ } // there are some sole activities exist in this LD,append them into - // sorted list end. + // sorted list end. if (activities.size() > 0) { sortedActList.addAll(activities.values()); } return sortedActList; } /** - * Move LAMS tool.xml from tool folder to export content root folder and - * modify it to {toolContentID}.xml file. Cache all attachement files - * from this tool into ArrayList, which will be save into a temporary - * file (resources.xml) and used by XSLT. + * Move LAMS tool.xml from tool folder to export content root folder and modify it to {toolContentID}.xml file. + * Cache all attachement files from this tool into ArrayList, which will be save into a temporary file + * (resources.xml) and used by XSLT. * * @param rootDir * @param activity @@ -1088,15 +1080,15 @@ Document doc = sax.build(new FileInputStream(toolFile)); Element root = doc.getRootElement(); // cache DTO object class and transform it into a tag : - // for later import use by XStream. + // for later import use by XStream. String mainObject = root.getName(); root.setName(activity.getToolSignature()); Namespace ns = Namespace.getNamespace(ExportToolContentService.IMS_TOOL_NS_PREFIX + activity.getToolSignature() + "_ims.xsd"); root.setNamespace(ns); // add mainObject tag: it save the Tool DTO class name. - // It is useful when importing by XStream + // It is useful when importing by XStream // (perhaps a future function) Element mainObjectEle = new Element(ExportToolContentService.IMS_TOOL_MAIN_OBJECT); mainObjectEle.setText(mainObject); @@ -1105,7 +1097,7 @@ updateNamespaceForChildren(root, ns); // create a new tools.xml file with toolContentID.xml as - // name. + // name. File imsToolFile = new File(FileUtil.getFullPath(xsltDir, activity.getToolContentID() .toString() + ".xml")); @@ -1118,19 +1110,19 @@ log.error("IMS export occurs error when reading tool xml for " + toolFileName + "."); } // tool node already gather into LD root folder - // imstools.xml file, delete old tool.xml from tool + // imstools.xml file, delete old tool.xml from tool // folder toolFile.delete(); continue; } // handle other attachment files from tools, treat them as - // resource of IMS package + // resource of IMS package List fileChildren = new ArrayList(); // resource TAG Element resEle = new Element(ExportToolContentService.IMS_TAG_RESOURCE); // the resource identifier should be - // "R_toolSignature_toolContentId" + // "R_toolSignature_toolContentId" Attribute resAtt = new Attribute(ExportToolContentService.IMS_ATTR_IDENTIFIER, ExportToolContentService.IMS_PREFIX_RESOURCE_IDENTIFIER + activity.getToolSignature() + "-" + activity.getToolContentID().toString()); @@ -1183,7 +1175,7 @@ // serialize tool xml into local file. XStream toolXml = new XStream(); // get back Xstream default convert, create proxy then register - // it to XStream parser. + // it to XStream parser. Converter c = toolXml.getConverterLookup().defaultConverter(); FileInvocationHandler handler = null; if (!fileHandleClassList.isEmpty()) { @@ -1244,9 +1236,8 @@ } /** - * Import the learning design from the given path. Set the importer as - * the creator. If the workspaceFolderUid is null then saves the design - * in the user's own workspace folder. + * Import the learning design from the given path. Set the importer as the creator. If the workspaceFolderUid is + * null then saves the design in the user's own workspace folder. * * @param designFile * @param importer @@ -1278,13 +1269,13 @@ badFileType(ldErrorMsgs, filename, "Not a valid wddx/xml file"); } else { // IExportToolContentService service = - // getExportService(); + // getExportService(); ldId = importLearningDesignV102(wddxPacket, importer, workspaceFolderUid, toolsErrorMsgs); } } else if (extension.equalsIgnoreCase(".zip")) { // write the file // String ldPath = - // ZipFileUtil.expandZip(file.getInputStream(),filename); + // ZipFileUtil.expandZip(file.getInputStream(),filename); String ldPath = ZipFileUtil.expandZip(new FileInputStream(designFile), filename); File fullFilePath = new File(FileUtil.getFullPath(ldPath, @@ -1327,8 +1318,8 @@ * * @return learningDesingID * @throws ExportToolContentException - * @see org.lamsfoundation.lams.authoring.service.IExportToolContentService.importLearningDesign102(String, - * User, WorkspaceFolder) + * @see org.lamsfoundation.lams.authoring.service.IExportToolContentService.importLearningDesign102(String, User, + * WorkspaceFolder) */ public Long importLearningDesignV102(String ldWddxPacket, User importer, Integer workspaceFolderUid, List toolsErrorMsgs) throws ImportToolContentException { @@ -1366,7 +1357,7 @@ String toolPath = FileUtil.getFullPath(learningDesignPath, activity.getToolContentID().toString()); // To create a new toolContent according to imported tool - // signature name. + // signature name. // get tool by signature Tool newTool = new ToolCompatibleStrategy().getTool(activity.getToolSignature()); @@ -1401,9 +1392,9 @@ ToolContentManager contentManager = (ToolContentManager) findToolService(newTool); // If this is a tool adapter tool, pass the customCSV to - // the special importToolContent method + // the special importToolContent method // Otherwise invoke the normal tool - // importToolContentMethod + // importToolContentMethod if (contentManager instanceof ToolAdapterContentManager) { ToolAdapterContentManager toolAdapterContentManager = (ToolAdapterContentManager) contentManager; toolAdapterContentManager.importToolContent(newContent.getToolContentId(), @@ -1419,7 +1410,7 @@ log.error(error, e); toolsErrorMsgs.add(error); // remove any unsucessed activities from new Learning - // design. + // design. removedActMap.put(activity.getActivityID(), activity); } } // end all activities import @@ -1450,7 +1441,7 @@ } // if the design was read only (e.g. exported a runtime - // sequence), clear the read only flag + // sequence), clear the read only flag ldDto.setDateReadOnly(null); ldDto.setReadOnly(false); @@ -1466,15 +1457,13 @@ } /** - * Call xstream to get the POJOs from the XML file. To make it - * backwardly compatible we catch any exceptions due to added fields, - * remove the field using the ToolContentVersionFilter functionality and - * try to reparse. We can't nominate the problem fields in advance as we - * are making XML created by newer versions of LAMS compatible with an + * Call xstream to get the POJOs from the XML file. To make it backwardly compatible we catch any exceptions due to + * added fields, remove the field using the ToolContentVersionFilter functionality and try to reparse. We can't + * nominate the problem fields in advance as we are making XML created by newer versions of LAMS compatible with an * older version. * - * This logic depends on the exception message containing the text. When - * we upgrade xstream, we must check that this message doesn't change. + * This logic depends on the exception message containing the text. When we upgrade xstream, we must check that this + * message doesn't change. * *

      * 	com.thoughtworks.xstream.converters.ConversionException: unknownField : unknownField
@@ -1497,7 +1486,7 @@
 	String lastFieldRemoved = "";
 	ToolContentVersionFilter contentFilter = null;
 	// cap the maximum number of retries to 30 - if we add more than 30 new
-        // fields then we need to rethink our
+	// fields then we need to rethink our
 	// strategy
 	int maxRetries = 30;
 	int numTries = 0;
@@ -1596,8 +1585,7 @@
     }
 
     /**
-     * Extract the class name or field name from a ConversionException
-     * message
+     * Extract the class name or field name from a ConversionException message
      */
     private String extractValue(String message, String fieldToLookFor) {
 	try {
@@ -1672,7 +1660,7 @@
 		filterVersion(toolFilePath, fromVersion, toVersion);
 	    }
 	    // clear and ensure next activity can get correct filter thru
-                // registerImportVersionFilterClass().
+	    // registerImportVersionFilterClass().
 	    filterClass = null;
 
 	    // read tool file after transform.
@@ -1686,7 +1674,7 @@
 		    Long uuid = NumberUtils.createLong(BeanUtils.getProperty(fileNode.instance,
 			    fileNode.name.uuidFieldName));
 		    // For instance, item class in share resource tool may
-                        // be url or single file. If it is URL, then the
+		    // be url or single file. If it is URL, then the
 		    // file uuid will be null. Ignore it!
 		    if (uuid == null) {
 			continue;
@@ -1707,15 +1695,15 @@
 		    log.debug("Tool attachement files/packages are going to upload to repository " + fullFileName);
 
 		    // to check if the file is package (with extension name
-                        // ".zip") or single file (no extension name).
+		    // ".zip") or single file (no extension name).
 		    File file = new File(fullFileName);
 		    boolean isPackage = false;
 		    if (!file.exists()) {
 			file = new File(fullFileName + ExportToolContentService.EXPORT_TOOLCONTNET_ZIP_SUFFIX);
 			realFileName = realFileName + ExportToolContentService.EXPORT_TOOLCONTNET_ZIP_SUFFIX;
 			isPackage = true;
 			// if this file is norpackage neither single file, throw
-                        // exception.
+			// exception.
 			if (!file.exists()) {
 			    throw new ImportToolContentException("Content attached file/package can not be found: "
 				    + fullFileName + "(.zip)");
@@ -1879,8 +1867,7 @@
     }
 
     /**
-     * If there are any errors happen during tool exporting content. Writing
-     * failed message to file.
+     * If there are any errors happen during tool exporting content. Writing failed message to file.
      */
     private void writeErrorToToolFile(String rootPath, Long toolContentId, String msg) {
 	// create tool's save path
@@ -1958,18 +1945,18 @@
 	Map activityByUIIDMapper = new HashMap();
 
 	// as we create the activities, we need to record any "default
-        // activities" for the sequence activity
+	// activities" for the sequence activity
 	// and branching activities to process later - we can't process them now
-        // as the children won't have
+	// as the children won't have
 	// been created yet and if we leave it till later and then find all the
-        // activities we are
+	// activities we are
 	// going through the activity set over and over again for no reason.
 	Map defaultActivityToParentActivityMapping = new HashMap();
 
 	for (AuthoringActivityDTO actDto : actDtoList) {
 	    Activity act = getActivity(actDto, groupingMapper, toolMapper, defaultActivityToParentActivityMapping);
 	    // so far, the activitiy ID is still old one, so setup the
-                // mapping relation between old ID and new activity.
+	    // mapping relation between old ID and new activity.
 	    activityMapper.put(act.getActivityId(), act);
 	    activityByUIIDMapper.put(act.getActivityUIID(), act);
 	    // if this act is removed, then does not save it into LD
@@ -1978,7 +1965,7 @@
 	    }
 	}
 	// rescan the activity list and refresh their parent activity and input
-        // activities
+	// activities
 	for (AuthoringActivityDTO actDto : actDtoList) {
 	    Activity act = activityMapper.get(actDto.getActivityID());
 	    if (removedActMap.containsKey(actDto.getActivityID())) {
@@ -1994,7 +1981,7 @@
 		} else {
 		    act.setParentActivity(parent);
 		    // also add child as Complex activity: It is useless for
-                        // persist data, but helpful for validate in
+		    // persist data, but helpful for validate in
 		    // learning design!
 		    if (parent.isComplexActivity()) {
 			Set set = ((ComplexActivity) parent).getActivities();
@@ -2028,16 +2015,16 @@
 	}
 
 	// Process the "first child" for any sequence activities and the
-        // "default branch" for branching activities.
+	// "default branch" for branching activities.
 	// If the child has been removed then leave it as null as the progress
-        // engine will cope (it will pick a
+	// engine will cope (it will pick a
 	// new one based on the lack of an input transition) and in authoring
-        // the author will just have to set
+	// the author will just have to set
 	// up a new first activity. If the default branch is missing and other
-        // details are missing (e.g. missing
+	// details are missing (e.g. missing
 	// conditions)
 	// from the design then it may have to be fixed in authoring before it
-        // will run, so the default branch missing
+	// will run, so the default branch missing
 	// case needs to be picked up by the validation (done later).
 	if (defaultActivityToParentActivityMapping.size() > 0) {
 	    for (Integer childUIID : defaultActivityToParentActivityMapping.keySet()) {
@@ -2075,7 +2062,7 @@
 			    boolean transitionBreak = true;
 			    for (TransitionDTO transDto : transDtoList) {
 				// find out the transition of current first
-                                // activity
+				// activity
 				if (nextActId.equals(transDto.getFromActivityID())) {
 				    transitionBreak = false;
 				    nextActId = transDto.getToActivityID();
@@ -2091,16 +2078,16 @@
 				    // already found the desire transition
 				    break;
 				    // if found flag is false yet, then it
-                                        // means the 2nd node remove as well,
+				    // means the 2nd node remove as well,
 				    // continue try 3rd...
 				}
 			    }
 			    // This activity also removed!!! then retrieve
-                                // again
+			    // again
 			    // If found is false, then the nextAct is still
-                                // not available, then continue find.
+			    // not available, then continue find.
 			    // tranisitionBreak mean the activity is removed
-                                // but it can not find its transition to
+			    // but it can not find its transition to
 			    // decide next available activity.
 			    if (found || transitionBreak) {
 				break;
@@ -2156,7 +2143,7 @@
 	    ld.setValidDesign(false);
 	    log.error(listOfValidationErrorDTOs);
 	    // throw new ImportToolContentException("Learning design
-                // validate error.");
+	    // validate error.");
 	} else {
 	    ld.setValidDesign(true);
 	}
@@ -2170,8 +2157,7 @@
     }
 
     /**
-     * Method to sort activity DTO according to the rule: Paretns is before
-     * their children.
+     * Method to sort activity DTO according to the rule: Paretns is before their children.
      * 
      * @param activities
      * @return
@@ -2181,7 +2167,7 @@
 	List actIdList = new ArrayList();
 
 	// NOTICE: this code can not handle all nodes have their parents, ie,
-        // there is at least one node parent is
+	// there is at least one node parent is
 	// null(root).
 	int failureToleranceCount = 5000;
 	while (!activities.isEmpty() && failureToleranceCount > 0) {
@@ -2213,12 +2199,10 @@
     }
 
     /**
-     * Get learning design object from this Learning design DTO object. It
-     * also following our import rules:
+     * Get learning design object from this Learning design DTO object. It also following our import rules:
      * 
  • lams_license - Assume same in all lams system. Import same ID
  • *
  • lams_copy_type - Set to 1.This indicates it is "normal" design.
  • - *
  • lams_workspace_folder - An input parameters to let user choose - * import workspace
  • + *
  • lams_workspace_folder - An input parameters to let user choose import workspace
  • *
  • User - The person who execute import action
  • *
  • OriginalLearningDesign - set to null
  • * @@ -2331,6 +2315,8 @@ ((LearnerChoiceGrouping) grouping).setNumberOfGroups(groupingDto.getNumberOfGroups()); ((LearnerChoiceGrouping) grouping).setEqualNumberOfLearnersPerGroup(groupingDto .getEqualNumberOfLearnersPerGroup()); + ((LearnerChoiceGrouping) grouping).setViewStudentsBeforeSelection(groupingDto + .getViewStudentsBeforeSelection()); } else { log.error("Unable to determine the grouping type. Creating a random grouping. GroupingDTO was " + groupingDto); @@ -2365,15 +2351,12 @@ } /** - * Creates the map entry between a branch sequence activity and a group. - * We need the group maps and the activity maps so that we can update - * the ids to the groups and the activities. Therefore this method must - * be done after all the groups are imported and the activities are - * imported. + * Creates the map entry between a branch sequence activity and a group. We need the group maps and the activity + * maps so that we can update the ids to the groups and the activities. Therefore this method must be done after all + * the groups are imported and the activities are imported. * - * Note: there isn't an set in the learning design for the branch - * mappings. The group objects actually contain the link to the - * mappings, so this method updates the group objects. + * Note: there isn't an set in the learning design for the branch mappings. The group objects actually contain the + * link to the mappings, so this method updates the group objects. */ private BranchActivityEntry getBranchActivityEntry(BranchActivityEntryDTO entryDto, Map groupByUIIDMapper, Map activityByUIIDMapper) { @@ -2441,7 +2424,7 @@ trans.setFromActivity(fromAct); trans.setFromUIID(fromAct.getActivityUIID()); // also set transition to activity: It is nonsense for persisit data, - // but it is help this learning design + // but it is help this learning design // validated fromAct.setTransitionTo(trans); // set to null @@ -2452,7 +2435,7 @@ trans.setToActivity(toAct); trans.setToUIID(toAct.getActivityUIID()); // also set transition to activity: It is nonsense for persisit data, - // but it is help this learning design + // but it is help this learning design // validated toAct.setTransitionFrom(trans); @@ -2485,10 +2468,10 @@ switch (act.getActivityTypeId()) { case Activity.TOOL_ACTIVITY_TYPE: // get back the toolContent in new system by activityID in - // old system. + // old system. ToolContent content = toolMapper.get(actDto.getActivityID()); // if activity can not find matching tool, the content should be - // null. + // null. if (content != null) { ((ToolActivity) act).setTool(content.getTool()); ((ToolActivity) act).setToolContentId(content.getToolContentId()); @@ -2592,7 +2575,7 @@ act.setOrderId(actDto.getOrderID()); // temporarily set as to null, after scan all activities, then set it to - // valid value. + // valid value. act.setParentActivity(null); act.setParentUIID(actDto.getParentUIID()); Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java =================================================================== diff -u -r1fe0f4f546903187be6f35e4d5c027853da9408c -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (.../WDDXTAGS.java) (revision 1fe0f4f546903187be6f35e4d5c027853da9408c) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (.../WDDXTAGS.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -112,7 +112,7 @@ /** FloatingActivity specific tags */ public static final String MAX_ACTIVITIES = "maxActivities"; - + /** OptionsActivity specific tags */ public static final String MAX_OPTIONS = "maxOptions"; public static final String MIN_OPTIONS = "minOptions"; @@ -146,6 +146,7 @@ public static final String GROUPING_DTO = "groupingDTO"; public static final String GROUPS = "groups"; public static final String EQUAL_NUMBER_OF_LEARNERS_PER_GROUP = "equalNumberOfLearnersPerGroup"; + public static final String VIEW_STUDENTS_BEFORE_SELECTION = "viewStudentsBeforeSelection"; public static final String GROUP_ID = "groupID"; public static final String GROUP_NAME = "groupName"; Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java =================================================================== diff -u -rc209be8131f22f6fe37bd8d6c14b56425a78b766 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java (.../ICoreLearnerService.java) (revision c209be8131f22f6fe37bd8d6c14b56425a78b766) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/ICoreLearnerService.java (.../ICoreLearnerService.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -30,6 +30,7 @@ import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.GateActivity; +import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; @@ -41,282 +42,347 @@ import org.lamsfoundation.lams.util.MessageService; /** - * - * All Learner service methods that are available within the core. These methods may require - * all the tool's Spring context files to be loaded, in addition to the core Spring context files. - * Hence it should only be used from lams-learning, lams-monitoring, lams-central wars. + * + * All Learner service methods that are available within the core. These methods may require all the tool's Spring + * context files to be loaded, in addition to the core Spring context files. Hence it should only be used from + * lams-learning, lams-monitoring, lams-central wars. */ public interface ICoreLearnerService extends ILearnerService { - /** Get the I18N service. Used by actions for internationalising errors that go back to Flash */ - public MessageService getMessageService(); + /** Get the I18N service. Used by actions for internationalising errors that go back to Flash */ + public MessageService getMessageService(); - /** Get the user service. Used when the action needs the real user object, not just the userId */ - public IUserManagementService getUserManagementService(); + /** Get the user service. Used when the action needs the real user object, not just the userId */ + public IUserManagementService getUserManagementService(); - /** - * Gets the lesson object for the given key. - * - */ - public Lesson getLesson(Long lessonID); + /** + * Gets the lesson object for the given key. + * + */ + public Lesson getLesson(Long lessonID); - /** - * Get the lesson data for a particular lesson. In a DTO format suitable for sending to the client. - */ - public LessonDTO getLessonData(Long lessonId); + /** + * Get the lesson data for a particular lesson. In a DTO format suitable for sending to the client. + */ + public LessonDTO getLessonData(Long lessonId); - /** - * Joins a User to a a new lesson as a learner - * @param learnerId the Learner's userID - * @param lessionID identifies the Lesson to start - * @throws LearnerServiceException in case of problems. - */ - public LearnerProgress joinLesson(Integer learnerId, Long lessonID); + /** + * Joins a User to a a new lesson as a learner + * + * @param learnerId + * the Learner's userID + * @param lessionID + * identifies the Lesson to start + * @throws LearnerServiceException + * in case of problems. + */ + public LearnerProgress joinLesson(Integer learnerId, Long lessonID); - /** - * This method navigate through all the tool activities for the given - * activity. For each tool activity, we look up the database - * to check up the existance of correspondent tool session. If the tool - * session doesn't exist, we create a new tool session instance. - * - * @param learnerProgress the learner progress we are processing. - * @throws LamsToolServiceException - */ - public void createToolSessionsIfNecessary(Activity activity, LearnerProgress learnerProgress); + /** + * This method navigate through all the tool activities for the given activity. For each tool activity, we look up + * the database to check up the existance of correspondent tool session. If the tool session doesn't exist, we + * create a new tool session instance. + * + * @param learnerProgress + * the learner progress we are processing. + * @throws LamsToolServiceException + */ + public void createToolSessionsIfNecessary(Activity activity, LearnerProgress learnerProgress); - /** - * Returns the current progress data of the User. - * @param learnerId the Learner's userID - * @param lessonId the Lesson to get progress from. - * @return LearnerProgess contains the learner's progress for the lesson. - * @throws LearnerServiceException in case of problems. - */ - public LearnerProgress getProgress(Integer learnerId, Long lessonId); + /** + * Returns the current progress data of the User. + * + * @param learnerId + * the Learner's userID + * @param lessonId + * the Lesson to get progress from. + * @return LearnerProgess contains the learner's progress for the lesson. + * @throws LearnerServiceException + * in case of problems. + */ + public LearnerProgress getProgress(Integer learnerId, Long lessonId); - /** - * Returns the current progress data, in the DTO format required by the jsp progress screen, of the User. - * @param learnerId the Learner's userID - * @param lessonId the Lesson to get progress from. - * @return Array of two objects. [0] List, [1] Activity ID of the current activity - * @throws LearnerServiceException in case of problems. - */ - public Object[] getStructuredActivityURLs(Integer learnerId, Long lessonId); + /** + * Returns the current progress data, in the DTO format required by the jsp progress screen, of the User. + * + * @param learnerId + * the Learner's userID + * @param lessonId + * the Lesson to get progress from. + * @return Array of two objects. [0] List, [1] Activity ID of the current activity + * @throws LearnerServiceException + * in case of problems. + */ + public Object[] getStructuredActivityURLs(Integer learnerId, Long lessonId); - /** - * Return the current progress data against progress id. - * @param progressId - * @return - */ - public LearnerProgress getProgressById(Long progressId); + /** + * Return the current progress data against progress id. + * + * @param progressId + * @return + */ + public LearnerProgress getProgressById(Long progressId); - /** - * Return the current progress data for a user for a lesson - * Returns a DTO suitable to send to Flash. - * @param lesson id - * @param learner id - * @return - */ - public LearnerProgressDTO getProgressDTOByLessonId(Long lessonId, Integer learnerId); + /** + * Return the current progress data for a user for a lesson Returns a DTO suitable to send to Flash. + * + * @param lesson + * id + * @param learner + * id + * @return + */ + public LearnerProgressDTO getProgressDTOByLessonId(Long lessonId, Integer learnerId); - /** - * Marks an activity as attempted. Called when a user selects an OptionsActivity. - * @param learnerId the Learner's userID - * @param lessonId the Lesson to get progress from. - * @param activity the activity being attempted. - * @param clearCompletedFlag If the lesson is completed but this activity is unstarted, should we mark it as incomplete? Used for branching and - * optional sequences for skipped sequences (e.g. force completed branching) - * @return LearnerProgress - */ - public LearnerProgress chooseActivity(Integer learnerId, Long lessonId, Activity activity, Boolean clearCompletedFlag); + /** + * Marks an activity as attempted. Called when a user selects an OptionsActivity. + * + * @param learnerId + * the Learner's userID + * @param lessonId + * the Lesson to get progress from. + * @param activity + * the activity being attempted. + * @param clearCompletedFlag + * If the lesson is completed but this activity is unstarted, should we mark it as incomplete? Used + * for branching and optional sequences for skipped sequences (e.g. force completed branching) + * @return LearnerProgress + */ + public LearnerProgress chooseActivity(Integer learnerId, Long lessonId, Activity activity, + Boolean clearCompletedFlag); - /** - * Calculates learner progress and returns the data required to be displayed to the learner (including URL(s)). - * This method is included in the interface for testing purposes. - * - * @param completedActivityID identifies the activity just completed - * @param learner the Learner - * @return the bean containing the display data for the Learner - * @throws LearnerServiceException in case of problems. - */ - public LearnerProgress calculateProgress(Activity completedActivity, Integer learnerId, LearnerProgress currentLearnerProgress); + /** + * Calculates learner progress and returns the data required to be displayed to the learner (including URL(s)). This + * method is included in the interface for testing purposes. + * + * @param completedActivityID + * identifies the activity just completed + * @param learner + * the Learner + * @return the bean containing the display data for the Learner + * @throws LearnerServiceException + * in case of problems. + */ + public LearnerProgress calculateProgress(Activity completedActivity, Integer learnerId, + LearnerProgress currentLearnerProgress); - /** - * Complete the activity in the progress engine and delegate to the progress - * engine to calculate the next activity in the learning design. - * It is currently triggered by various progress engine related action classes, - * which then calculate the url to go to next, based on the ActivityMapping - * class. - * - * @param learnerId the learner who are running this activity in the design. - * @param activity the activity is being run. - * @param lessonId lesson id - * @return the updated learner progress - */ - public LearnerProgress completeActivity(Integer learnerId, Activity activity, LearnerProgress progress); + /** + * Complete the activity in the progress engine and delegate to the progress engine to calculate the next activity + * in the learning design. It is currently triggered by various progress engine related action classes, which then + * calculate the url to go to next, based on the ActivityMapping class. + * + * @param learnerId + * the learner who are running this activity in the design. + * @param activity + * the activity is being run. + * @param lessonId + * lesson id + * @return the updated learner progress + */ + public LearnerProgress completeActivity(Integer learnerId, Activity activity, LearnerProgress progress); - /** - * Same as LearnerProgress completeActivity(Integer learnerId,Activity activity,LearnerProgress progress) - * except that the it works out the current learner's progress from the given lesson id. - * - * Use the other method if you already have the learner progress, as this method looks up the learner - * progress. - * - * @param learnerId the learner who are running this activity in the design. - * @param activity the activity is being run. - * @param lessonId lesson id - * @return the updated learner progress - */ - public LearnerProgress completeActivity(Integer learnerId, Activity activity, Long lessonId); + /** + * Same as LearnerProgress completeActivity(Integer learnerId,Activity activity,LearnerProgress progress) except + * that the it works out the current learner's progress from the given lesson id. + * + * Use the other method if you already have the learner progress, as this method looks up the learner progress. + * + * @param learnerId + * the learner who are running this activity in the design. + * @param activity + * the activity is being run. + * @param lessonId + * lesson id + * @return the updated learner progress + */ + public LearnerProgress completeActivity(Integer learnerId, Activity activity, Long lessonId); - /** - * Retrieve all lessons that has been started, suspended or finished. All - * finished but archived lesson should not be loaded. - * @param learner the user who intend to start a lesson - * @return a list of active lessons. - */ - public LessonDTO[] getActiveLessonsFor(Integer learnerId); + /** + * Retrieve all lessons that has been started, suspended or finished. All finished but archived lesson should not be + * loaded. + * + * @param learner + * the user who intend to start a lesson + * @return a list of active lessons. + */ + public LessonDTO[] getActiveLessonsFor(Integer learnerId); - /** - * Mark the learner progress as restarting to indicate the current learner - * has exit the lesson. Doesn't use the cached progress object in case it - * - * @param userId - * @param lessonId - */ - public void exitLesson(Integer learnerId, Long lessonId); + /** + * Mark the learner progress as restarting to indicate the current learner has exit the lesson. Doesn't use the + * cached progress object in case it + * + * @param userId + * @param lessonId + */ + public void exitLesson(Integer learnerId, Long lessonId); - /** - * Returns an activity according to the activity id. - * @param activityId the activity id. - * @return the activity requested. - */ - public Activity getActivity(Long activityId); + /** + * Returns an activity according to the activity id. + * + * @param activityId + * the activity id. + * @return the activity requested. + */ + public Activity getActivity(Long activityId); - /** - * Returns all the active learners by the lesson id. - * @param lessonId the requested lesson id. - * @return the list of learners. - */ - public List getActiveLearnersByLesson(long lessonId); + /** + * Returns all the active learners by the lesson id. + * + * @param lessonId + * the requested lesson id. + * @return the list of learners. + */ + public List getActiveLearnersByLesson(long lessonId); - /** - * Returns a count of all the active learners by lesson id. - * More efficient than calling getActiveLearnersByLesson(lessonId).size() - */ - public Integer getCountActiveLearnersByLesson(long lessonId); + /** + * Returns a count of all the active learners by lesson id. More efficient than calling + * getActiveLearnersByLesson(lessonId).size() + */ + public Integer getCountActiveLearnersByLesson(long lessonId); - /** - * Perform grouping for the learners who have started the lesson, - * based on the grouping activity. - * - * @param lessonId lesson id - * @param groupingActivityId the activity that has create grouping. - * @param learnerId the learner who triggers the grouping. - * @param forceGrouping if forceGrouping==true and the lesson is a preview lesson then the groupings is done irrespective of the grouping type - * @return true if grouping done, false if waiting for grouping to occur - */ - public boolean performGrouping(Long lessonId, Long groupingActivityId, Integer learnerId, boolean forceGrouping); + /** + * Perform grouping for the learners who have started the lesson, based on the grouping activity. + * + * @param lessonId + * lesson id + * @param groupingActivityId + * the activity that has create grouping. + * @param learnerId + * the learner who triggers the grouping. + * @param forceGrouping + * if forceGrouping==true and the lesson is a preview lesson then the groupings is done irrespective + * of the grouping type + * @return true if grouping done, false if waiting for grouping to occur + */ + public boolean performGrouping(Long lessonId, Long groupingActivityId, Integer learnerId, boolean forceGrouping); - /** - * Perform grouping for the learner, depending on his/hers choice. - * @param lessonId lesson id - * @param groupingActivityId the activity that create grouping. - * @param groupId id of the group chosen by the learner - * @param learnerId the learner who triggers the grouping. - * @return true if the learner was successfully added to the group; false if the group was empty - * @throws LearnerServiceException - */ - public boolean learnerChooseGroup(Long lessonId, Long groupingActivityId, Long groupId, Integer learnerId) - throws LearnerServiceException; + /** + * Perform grouping for the learner, depending on his/hers choice. + * + * @param lessonId + * lesson id + * @param groupingActivityId + * the activity that create grouping. + * @param groupId + * id of the group chosen by the learner + * @param learnerId + * the learner who triggers the grouping. + * @return true if the learner was successfully added to the group; false if the group was empty + * @throws LearnerServiceException + */ + public boolean learnerChooseGroup(Long lessonId, Long groupingActivityId, Long groupId, Integer learnerId) + throws LearnerServiceException; - /** - * Returns the maximum number of learners per group in learner's choice grouping. - * @param lessonId id of the lesson - * @param groupingId id of the grouping activity - * @return the maximum number of learners per group;null if the requirement for equal number of learners in groups was not set - */ - public Integer calculateMaxNumberOfLearnersPerGroup(Long lessonId, Long groupingId); + /** + * Returns the maximum number of learners per group in learner's choice grouping. + * + * @param lessonId + * id of the lesson + * @param groupingId + * id of the grouping activity + * @return the maximum number of learners per group;null if the requirement for equal number of + * learners in groups was not set + */ + public Integer calculateMaxNumberOfLearnersPerGroup(Long lessonId, Grouping grouping); - /** - * Check up the gate status to go through the gate. This also updates the gate. - * This method should be used when we do not have an grouping activity - * that is already part of the Hibernate session. - * @param gateid the gate that current learner is facing. It could be - * synch gate, schedule gate or permission gate. - * @param knocker the learner who wants to go through the gate. - * @param forceGate if forceGate==true and the lesson is a preview lesson then the gate is opened straight away. - * @return Updated gate details - */ - public GateActivityDTO knockGate(Long gateActivityId, User knocker, boolean forceGate); + public Grouping getGrouping(Long groupingId); - /** - * Check up the gate status to go through the gate. This also updates the gate. - * This method should be used when we do have an grouping activity - * that is already part of the Hibernate session. - * @param gate the gate that current learner is facing. It could be - * synch gate, schedule gate or permission gate. - * Don't supply the actual gate from the cached web version - * as it might be out of date or not attached to the session - * @param knocker the learner who wants to go through the gate. - * @param forceGate if forceGate==true and the lesson is a preview lesson then the gate is opened straight away. - * @return Updated gate details - */ - public GateActivityDTO knockGate(GateActivity gateActivity, User knocker, boolean forceGate); + /** + * Check up the gate status to go through the gate. This also updates the gate. This method should be used when we + * do not have an grouping activity that is already part of the Hibernate session. + * + * @param gateid + * the gate that current learner is facing. It could be synch gate, schedule gate or permission gate. + * @param knocker + * the learner who wants to go through the gate. + * @param forceGate + * if forceGate==true and the lesson is a preview lesson then the gate is opened straight away. + * @return Updated gate details + */ + public GateActivityDTO knockGate(Long gateActivityId, User knocker, boolean forceGate); - /** - * Get all the learners who may come through this gate. - * For a Group Based branch and the Teacher Grouped branch, it is the group of users in - * the Branch's group, but only the learners who have started the lesson. - * Otherwise we just get all learners who have started the lesson. - * @param gate activity - * @return List of User - */ - public List getLearnersForGate(GateActivity gate); + /** + * Check up the gate status to go through the gate. This also updates the gate. This method should be used when we + * do have an grouping activity that is already part of the Hibernate session. + * + * @param gate + * the gate that current learner is facing. It could be synch gate, schedule gate or permission gate. + * Don't supply the actual gate from the cached web version as it might be out of date or not + * attached to the session + * @param knocker + * the learner who wants to go through the gate. + * @param forceGate + * if forceGate==true and the lesson is a preview lesson then the gate is opened straight away. + * @return Updated gate details + */ + public GateActivityDTO knockGate(GateActivity gateActivity, User knocker, boolean forceGate); - /** - * Get the learner url for a particular activity. - * - * @param learnerId - * @param activityId - */ - public String getLearnerActivityURL(Integer learnerId, Long activityId); + /** + * Get all the learners who may come through this gate. For a Group Based branch and the Teacher Grouped branch, it + * is the group of users in the Branch's group, but only the learners who have started the lesson. Otherwise we just + * get all learners who have started the lesson. + * + * @param gate + * activity + * @return List of User + */ + public List getLearnersForGate(GateActivity gate); - /** - * Get the lesson for this activity. If the activity is not part of a lesson (ie is from an authoring - * design then it will return null. - */ - public Lesson getLessonByActivity(Activity activity); + /** + * Get the learner url for a particular activity. + * + * @param learnerId + * @param activityId + */ + public String getLearnerActivityURL(Integer learnerId, Long activityId); - /** - * - * @param learnerId the learner who triggers the move - * @param lessonId lesson id - * @param fromActivity Activity moving from - * @param toActivity Activity moving to (being run) - * @return updated Learner Progress - */ - public LearnerProgress moveToActivity(Integer learnerId, Long lessonId, Activity fromActivity, Activity toActivity); + /** + * Get the lesson for this activity. If the activity is not part of a lesson (ie is from an authoring design then it + * will return null. + */ + public Lesson getLessonByActivity(Activity activity); - /** - * Work out which branch to which a user should go. If the current lesson is a preview lesson, it will force - * the user to a branch if at all possible. - * - * @param lesson current lesson. - * @param BranchingActivity the branching activity - * @param learnerId the learner who triggers the grouping. - * @throws LearnerServiceException - */ - public SequenceActivity determineBranch(Lesson lesson, BranchingActivity branchingActivity, Integer learnerId) - throws LearnerServiceException; + /** + * + * @param learnerId + * the learner who triggers the move + * @param lessonId + * lesson id + * @param fromActivity + * Activity moving from + * @param toActivity + * Activity moving to (being run) + * @return updated Learner Progress + */ + public LearnerProgress moveToActivity(Integer learnerId, Long lessonId, Activity fromActivity, Activity toActivity); - /** - * 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; + /** + * Work out which branch to which a user should go. If the current lesson is a preview lesson, it will force the + * user to a branch if at all possible. + * + * @param lesson + * current lesson. + * @param BranchingActivity + * the branching activity + * @param learnerId + * the learner who triggers the grouping. + * @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 -r979d510687c84790a56c7fab0c7ecef34cb59a24 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision 979d510687c84790a56c7fab0c7ecef34cb59a24) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerService.java (.../LearnerService.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -38,7 +38,6 @@ import org.lamsfoundation.lams.learning.progress.ProgressBuilder; import org.lamsfoundation.lams.learning.progress.ProgressEngine; import org.lamsfoundation.lams.learning.progress.ProgressException; -import org.lamsfoundation.lams.learning.web.bean.ActivityURL; import org.lamsfoundation.lams.learning.web.bean.GateActivityDTO; import org.lamsfoundation.lams.learning.web.util.ActivityMapping; import org.lamsfoundation.lams.learningdesign.Activity; @@ -74,7 +73,6 @@ import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.MessageService; -import org.lamsfoundation.lams.web.util.SessionMap; import org.springframework.dao.DeadlockLoserDataAccessException; /** @@ -100,7 +98,6 @@ private ILessonService lessonService; private static HashMap syncMap = new HashMap(); protected MessageService messageService; - // --------------------------------------------------------------------- // Inversion of Control Methods - Constructor injection @@ -386,7 +383,8 @@ builder.parseLearningDesign(); Object[] retValue = new Object[2]; - retValue[0] = (List) builder.getActivityList();; + retValue[0] = builder.getActivityList(); + ; retValue[1] = progress.getCurrentActivity() != null ? progress.getCurrentActivity().getActivityId() : null; return retValue; @@ -413,7 +411,7 @@ } progressEngine.setActivityAttempted(progress, activity); - + progress.setCurrentActivity(activity); progress.setNextActivity(activity); @@ -428,61 +426,63 @@ * java.lang.Long, org.lamsfoundation.lams.learningdesign.Activity, * org.lamsfoundation.lams.learningdesign.Activity) */ - public LearnerProgress moveToActivity(Integer learnerId, Long lessonId, Activity fromActivity, Activity toActivity) throws LearnerServiceException { + public LearnerProgress moveToActivity(Integer learnerId, Long lessonId, Activity fromActivity, Activity toActivity) + throws LearnerServiceException { int count = 0; - LearnerProgress progress = null; - + LearnerProgress progress = null; + // wait till lock is released - while(syncMap.containsKey(learnerId)) { - count++; - try { - Thread.sleep(1000); - - if(count > 100) { - throw new LearnerServiceException("Thread wait count exceeded limit."); - } - - } catch (InterruptedException e1) { - throw new LearnerServiceException("While retrying to move activity, thread was interrupted.", e1); + while (LearnerService.syncMap.containsKey(learnerId)) { + count++; + try { + Thread.sleep(1000); + + if (count > 100) { + throw new LearnerServiceException("Thread wait count exceeded limit."); } - } - - // lock - try { - - syncMap.put(learnerId, lessonId); - + + } catch (InterruptedException e1) { + throw new LearnerServiceException("While retrying to move activity, thread was interrupted.", e1); + } + } + + // lock + try { + + LearnerService.syncMap.put(learnerId, lessonId); + progress = learnerProgressDAO.getLearnerProgressByLearner(learnerId, lessonId); - - if (fromActivity != null && fromActivity.getActivityId() != progress.getCurrentActivity().getActivityId()) { - progress.setProgressState(fromActivity, LearnerProgress.ACTIVITY_ATTEMPTED, activityDAO); + + if (fromActivity != null && fromActivity.getActivityId() != progress.getCurrentActivity().getActivityId()) { + progress.setProgressState(fromActivity, LearnerProgress.ACTIVITY_ATTEMPTED, activityDAO); + } + + if (toActivity != null) { + progress.setProgressState(toActivity, LearnerProgress.ACTIVITY_ATTEMPTED, activityDAO); + + if (!toActivity.getReadOnly()) { + toActivity.setReadOnly(true); + activityDAO.update(toActivity); } - - if (toActivity != null) { - progress.setProgressState(toActivity, LearnerProgress.ACTIVITY_ATTEMPTED, activityDAO); - - if(!toActivity.getReadOnly()) { - toActivity.setReadOnly(true); - activityDAO.update(toActivity); - } - - if(!toActivity.isFloating()) { - progress.setCurrentActivity(toActivity); - progress.setNextActivity(toActivity); - } + + if (!toActivity.isFloating()) { + progress.setCurrentActivity(toActivity); + progress.setNextActivity(toActivity); } - - learnerProgressDAO.updateLearnerProgress(progress); - } catch(Exception e) { - throw new LearnerServiceException(e.getMessage()); - } finally { - // remove lock - if(syncMap.containsKey(learnerId)) - syncMap.remove(learnerId); - } - + } + + learnerProgressDAO.updateLearnerProgress(progress); + } catch (Exception e) { + throw new LearnerServiceException(e.getMessage()); + } finally { + // remove lock + if (LearnerService.syncMap.containsKey(learnerId)) { + LearnerService.syncMap.remove(learnerId); + } + } + return progress; - + } /** @@ -1267,30 +1267,35 @@ /** * {@inheritDoc} */ - public Integer calculateMaxNumberOfLearnersPerGroup(Long lessonId, Long groupingId) { + public Integer calculateMaxNumberOfLearnersPerGroup(Long lessonId, Grouping grouping) { Lesson lesson = getLesson(lessonId); - LearnerChoiceGrouping grouping = (LearnerChoiceGrouping) groupingDAO.getGroupingById(groupingId); + LearnerChoiceGrouping learnerChoiceGrouping = (LearnerChoiceGrouping) grouping; Integer maxNumberOfLearnersPerGroup = null; int learnerCount = lesson.getAllLearners().size(); int groupCount = grouping.getGroups().size(); - if (grouping.getLearnersPerGroup() == null) { + if (learnerChoiceGrouping.getLearnersPerGroup() == null) { if (groupCount == 0) { - ((LearnerChoiceGrouper) grouping.getGrouper()).createGroups(grouping, 2); + ((LearnerChoiceGrouper) grouping.getGrouper()).createGroups(learnerChoiceGrouping, 2); groupCount = grouping.getGroups().size(); groupingDAO.update(grouping); } - if (grouping.getEqualNumberOfLearnersPerGroup()) { + if (learnerChoiceGrouping.getEqualNumberOfLearnersPerGroup()) { maxNumberOfLearnersPerGroup = learnerCount / groupCount + (learnerCount % groupCount == 0 ? 0 : 1); } } else { - maxNumberOfLearnersPerGroup = grouping.getLearnersPerGroup(); + maxNumberOfLearnersPerGroup = learnerChoiceGrouping.getLearnersPerGroup(); int desiredGroupCount = learnerCount / maxNumberOfLearnersPerGroup + (learnerCount % maxNumberOfLearnersPerGroup == 0 ? 0 : 1); if (desiredGroupCount > groupCount) { - ((LearnerChoiceGrouper) grouping.getGrouper()).createGroups(grouping, desiredGroupCount - groupCount); + ((LearnerChoiceGrouper) grouping.getGrouper()).createGroups(learnerChoiceGrouping, desiredGroupCount + - groupCount); groupingDAO.update(grouping); } } return maxNumberOfLearnersPerGroup; } -} + + public Grouping getGrouping(Long groupingId) { + return groupingDAO.getGroupingById(groupingId); + } +} \ No newline at end of file Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GroupingAction.java =================================================================== diff -u -rc209be8131f22f6fe37bd8d6c14b56425a78b766 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GroupingAction.java (.../GroupingAction.java) (revision c209be8131f22f6fe37bd8d6c14b56425a78b766) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/GroupingAction.java (.../GroupingAction.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -46,6 +46,7 @@ import org.lamsfoundation.lams.learningdesign.GroupComparator; import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.GroupingActivity; +import org.lamsfoundation.lams.learningdesign.LearnerChoiceGrouping; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.util.WebUtil; @@ -54,229 +55,238 @@ /** * - *

    The action servlet that triggers the system driven grouping - * (random grouping) and allows the learner to view the result of the grouping. + *

    + * The action servlet that triggers the system driven grouping (random grouping) and allows the learner to view the + * result of the grouping. *

    * - *

    Has a special override key - if the parameter force is set and the - * lesson is a preview lesson, any chosen grouping will be overridden. + *

    + * Has a special override key - if the parameter force is set and the lesson is a preview lesson, any chosen grouping + * will be overridden. *

    + * * @author Jacky Fang - * @since 2005-3-29 + * @since 2005-3-29 * @version 1.1 * * ----------------XDoclet Tags-------------------- * - * @struts:action name = "GroupingForm" - * path="/grouping" - * parameter="method" - * validate="false" + * @struts:action name = "GroupingForm" path="/grouping" parameter="method" validate="false" * @struts:action-forward name="viewGroup" path="/grouping.do?method=viewGrouping" * @struts:action-forward name="showGroup" path=".showgroup" * @struts:action-forward name="waitGroup" path=".waitgroup" - * @struts:action-forward name="chooseGroup" path=".choosegroup" - * ----------------XDoclet Tags-------------------- + * @struts:action-forward name="chooseGroup" path=".choosegroup" ----------------XDoclet Tags-------------------- * */ public class GroupingAction extends LamsDispatchAction { - /** Input parameter. Boolean value */ - public static final String PARAM_FORCE_GROUPING = "force"; + /** Input parameter. Boolean value */ + public static final String PARAM_FORCE_GROUPING = "force"; - //--------------------------------------------------------------------- - // Instance variables - //--------------------------------------------------------------------- - private static Logger log = Logger.getLogger(GroupingAction.class); - //--------------------------------------------------------------------- - // Class level constants - Session Attributes - //--------------------------------------------------------------------- - public static final String GROUPS = "groups"; - public static final String FINISHED_BUTTON = "finishedButton"; - public static final String LOCAL_FILES = "localFiles"; - public static final String TITLE = "title"; - public static final String MAX_LEARNERS_PER_GROUP = "maxLearnersPerGroup"; + // --------------------------------------------------------------------- + // Instance variables + // --------------------------------------------------------------------- + private static Logger log = Logger.getLogger(GroupingAction.class); + // --------------------------------------------------------------------- + // Class level constants - Session Attributes + // --------------------------------------------------------------------- + public static final String GROUPS = "groups"; + public static final String FINISHED_BUTTON = "finishedButton"; + public static final String LOCAL_FILES = "localFiles"; + public static final String TITLE = "title"; + public static final String MAX_LEARNERS_PER_GROUP = "maxLearnersPerGroup"; + public static final String VIEW_STUDENTS_BEFORE_SELECTION = "viewStudentsBeforeSelection"; - //--------------------------------------------------------------------- - // Class level constants - Struts forward - //--------------------------------------------------------------------- - public static final String VIEW_GROUP = "viewGroup"; - public static final String WAIT_GROUP = "waitGroup"; - public static final String SHOW_GROUP = "showGroup"; - public static final String CHOOSE_GROUP = "chooseGroup"; + // --------------------------------------------------------------------- + // Class level constants - Struts forward + // --------------------------------------------------------------------- + public static final String VIEW_GROUP = "viewGroup"; + public static final String WAIT_GROUP = "waitGroup"; + public static final String SHOW_GROUP = "showGroup"; + public static final String CHOOSE_GROUP = "chooseGroup"; - //--------------------------------------------------------------------- - // Struts Dispatch Method - //--------------------------------------------------------------------- - /** - * Perform the grouping for the users who are currently running the lesson. - * If force is set to true, then we should be in preview mode, and we want to - * override the chosen grouping to make it group straight away. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - */ - public ActionForward performGrouping(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { + // --------------------------------------------------------------------- + // Struts Dispatch Method + // --------------------------------------------------------------------- + /** + * Perform the grouping for the users who are currently running the lesson. If force is set to true, then we should + * be in preview mode, and we want to override the chosen grouping to make it group straight away. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + */ + public ActionForward performGrouping(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { - boolean forceGroup = WebUtil.readBooleanParam(request, GroupingAction.PARAM_FORCE_GROUPING, false); + boolean forceGroup = WebUtil.readBooleanParam(request, GroupingAction.PARAM_FORCE_GROUPING, false); - //initialize service object - ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); - LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); - Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); - if (!(activity instanceof GroupingActivity)) { - GroupingAction.log.error(LamsDispatchAction.className + ": activity not GroupingActivity"); - return mapping.findForward(ActivityMapping.ERROR); - } - Long lessonId = learnerProgress.getLesson().getLessonId(); - boolean groupingDone = learnerService.performGrouping(lessonId, activity.getActivityId(), LearningWebUtil.getUserId(), - forceGroup); + // initialize service object + ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); + LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); + Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); + if (!(activity instanceof GroupingActivity)) { + GroupingAction.log.error(LamsDispatchAction.className + ": activity not GroupingActivity"); + return mapping.findForward(ActivityMapping.ERROR); + } + Long lessonId = learnerProgress.getLesson().getLessonId(); + boolean groupingDone = learnerService.performGrouping(lessonId, activity.getActivityId(), LearningWebUtil + .getUserId(), forceGroup); - LearningWebUtil.putActivityInRequest(request, activity, learnerService); + LearningWebUtil.putActivityInRequest(request, activity, learnerService); - DynaActionForm groupForm = (DynaActionForm) form; - groupForm.set("previewLesson", learnerProgress.getLesson().isPreviewLesson()); - groupForm.set("title", activity.getTitle()); + DynaActionForm groupForm = (DynaActionForm) form; + groupForm.set("previewLesson", learnerProgress.getLesson().isPreviewLesson()); + groupForm.set("title", activity.getTitle()); - LearningWebUtil.setupProgressInRequest(groupForm, request, learnerProgress); + LearningWebUtil.setupProgressInRequest(groupForm, request, learnerProgress); - if (groupingDone) { - request.setAttribute(GroupingAction.FINISHED_BUTTON, Boolean.TRUE); - return mapping.findForward(GroupingAction.VIEW_GROUP); - } - //forward to group choosing page - if (((GroupingActivity) activity).getCreateGrouping().isLearnerChoiceGrouping()) { - Integer maxNumberOfLeaernersPerGroup = learnerService.calculateMaxNumberOfLearnersPerGroup(lessonId, - ((GroupingActivity) activity).getCreateGrouping().getGroupingId()); - prepareGroupData(request); - request.setAttribute(GroupingAction.MAX_LEARNERS_PER_GROUP, maxNumberOfLeaernersPerGroup); - request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); - return mapping.findForward(GroupingAction.CHOOSE_GROUP); - } - return mapping.findForward(GroupingAction.WAIT_GROUP); + if (groupingDone) { + request.setAttribute(GroupingAction.FINISHED_BUTTON, Boolean.TRUE); + return mapping.findForward(GroupingAction.VIEW_GROUP); } + // forward to group choosing page + if (((GroupingActivity) activity).getCreateGrouping().isLearnerChoiceGrouping()) { + Long groupingId = ((GroupingActivity) activity).getCreateGrouping().getGroupingId(); - /** - * Load up the grouping information and forward to the jsp page to display - * all the groups and members. - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - */ - public ActionForward viewGrouping(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - prepareGroupData(request); - request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); - ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, true); - request.setAttribute(GroupingAction.FINISHED_BUTTON, new Boolean(mode == null || !mode.isTeacher())); + LearnerChoiceGrouping grouping = (LearnerChoiceGrouping) learnerService.getGrouping(groupingId); + Integer maxNumberOfLeaernersPerGroup = learnerService.calculateMaxNumberOfLearnersPerGroup(lessonId, + grouping); - return mapping.findForward(GroupingAction.SHOW_GROUP); + prepareGroupData(request); + request.setAttribute(GroupingAction.MAX_LEARNERS_PER_GROUP, maxNumberOfLeaernersPerGroup); + request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); + request.setAttribute(GroupingAction.VIEW_STUDENTS_BEFORE_SELECTION, grouping + .getViewStudentsBeforeSelection()); + return mapping.findForward(GroupingAction.CHOOSE_GROUP); } + return mapping.findForward(GroupingAction.WAIT_GROUP); + } - /** - * Do the export portfolio. Take the parameters from the standard String request parameters, don't expect - * attributes to be in the request - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - */ - public ActionForward exportPortfolio(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - prepareGroupData(request); - request.setAttribute(GroupingAction.FINISHED_BUTTON, Boolean.FALSE); - request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.TRUE); + /** + * Load up the grouping information and forward to the jsp page to display all the groups and members. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + */ + public ActionForward viewGrouping(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + prepareGroupData(request); + request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); + ToolAccessMode mode = WebUtil.readToolAccessModeParam(request, AttributeNames.PARAM_MODE, true); + request.setAttribute(GroupingAction.FINISHED_BUTTON, new Boolean(mode == null || !mode.isTeacher())); - return mapping.findForward(GroupingAction.SHOW_GROUP); - } + return mapping.findForward(GroupingAction.SHOW_GROUP); + } - /** - * Complete the current tool activity and forward to the url of next activity - * in the learning design. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - */ - public ActionForward completeActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - //initialize service object - ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); - LearnerProgress progress = LearningWebUtil.getLearnerProgress(request, learnerService); - Activity groupingActivity = LearningWebUtil.getActivityFromRequest(request, learnerService); - Integer learnerId = LearningWebUtil.getUserId(); + /** + * Do the export portfolio. Take the parameters from the standard String request parameters, don't expect attributes + * to be in the request + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + */ + public ActionForward exportPortfolio(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + prepareGroupData(request); + request.setAttribute(GroupingAction.FINISHED_BUTTON, Boolean.FALSE); + request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.TRUE); - // so manually resume the progress. The completeActivity code can cope with a missing activity. - return LearningWebUtil.completeActivity(request, response, LearningWebUtil.getActivityMapping(this.getServlet() - .getServletContext()), progress, groupingActivity, learnerId, learnerService, true); - } + return mapping.findForward(GroupingAction.SHOW_GROUP); + } - /** - * Inserts into the request most of the data required by JSP page. This method is common for several pages. - * @param request - */ - private void prepareGroupData(HttpServletRequest request) { + /** + * Complete the current tool activity and forward to the url of next activity in the learning design. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + */ + public ActionForward completeActivity(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + // initialize service object + ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); + LearnerProgress progress = LearningWebUtil.getLearnerProgress(request, learnerService); + Activity groupingActivity = LearningWebUtil.getActivityFromRequest(request, learnerService); + Integer learnerId = LearningWebUtil.getUserId(); - ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); + // so manually resume the progress. The completeActivity code can cope with a missing activity. + return LearningWebUtil.completeActivity(request, response, LearningWebUtil.getActivityMapping(this.getServlet() + .getServletContext()), progress, groupingActivity, learnerId, learnerService, true); + } - SortedSet groups = new TreeSet(new GroupComparator()); - Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); + /** + * Inserts into the request most of the data required by JSP page. This method is common for several pages. + * + * @param request + */ + private void prepareGroupData(HttpServletRequest request) { - Grouping grouping = ((GroupingActivity) activity).getCreateGrouping(); - if (grouping != null) { - groups.addAll(grouping.getGroups()); - } - request.setAttribute(GroupingAction.GROUPS, groups); - request.setAttribute(GroupingAction.TITLE, activity.getTitle()); - request.setAttribute(AttributeNames.PARAM_ACTIVITY_ID, activity.getActivityId()); - } + ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); - /** - * Responds to a learner's group choice. Might forward back to group choice page if the chosen group was full. - * @param mapping - * @param form - * @param request - * @param response - * @return - * @throws IOException - * @throws ServletException - */ - public ActionForward learnerChooseGroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); - Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); - Long groupId = WebUtil.readLongParam(request, "groupId"); - LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); - Long lessonId = learnerProgress.getLesson().getLessonId(); - boolean learnerGroupped = learnerService.learnerChooseGroup(lessonId, activity.getActivityId(), groupId, LearningWebUtil - .getUserId()); - if (learnerGroupped) { - return viewGrouping(mapping, form, request, response); - } + SortedSet groups = new TreeSet(new GroupComparator()); + Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); - Integer maxNumberOfLeaernersPerGroup = learnerService.calculateMaxNumberOfLearnersPerGroup(lessonId, - ((GroupingActivity) activity).getCreateGrouping().getGroupingId()); - prepareGroupData(request); - request.setAttribute(GroupingAction.MAX_LEARNERS_PER_GROUP, maxNumberOfLeaernersPerGroup); - request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); - return mapping.findForward(GroupingAction.CHOOSE_GROUP); + Grouping grouping = ((GroupingActivity) activity).getCreateGrouping(); + if (grouping != null) { + groups.addAll(grouping.getGroups()); } + request.setAttribute(GroupingAction.GROUPS, groups); + request.setAttribute(GroupingAction.TITLE, activity.getTitle()); + request.setAttribute(AttributeNames.PARAM_ACTIVITY_ID, activity.getActivityId()); + } + /** + * Responds to a learner's group choice. Might forward back to group choice page if the chosen group was full. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + * @throws IOException + * @throws ServletException + */ + public ActionForward learnerChooseGroup(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + ICoreLearnerService learnerService = LearnerServiceProxy.getLearnerService(getServlet().getServletContext()); + Activity activity = LearningWebUtil.getActivityFromRequest(request, learnerService); + Long groupId = WebUtil.readLongParam(request, "groupId"); + LearnerProgress learnerProgress = LearningWebUtil.getLearnerProgress(request, learnerService); + Long lessonId = learnerProgress.getLesson().getLessonId(); + boolean learnerGroupped = learnerService.learnerChooseGroup(lessonId, activity.getActivityId(), groupId, + LearningWebUtil.getUserId()); + if (learnerGroupped) { + return viewGrouping(mapping, form, request, response); + } + Long groupingId = ((GroupingActivity) activity).getCreateGrouping().getGroupingId(); + + LearnerChoiceGrouping grouping = (LearnerChoiceGrouping) learnerService.getGrouping(groupingId); + Integer maxNumberOfLeaernersPerGroup = learnerService.calculateMaxNumberOfLearnersPerGroup(lessonId, grouping); + + prepareGroupData(request); + request.setAttribute(GroupingAction.MAX_LEARNERS_PER_GROUP, maxNumberOfLeaernersPerGroup); + request.setAttribute(GroupingAction.LOCAL_FILES, Boolean.FALSE); + request.setAttribute(GroupingAction.VIEW_STUDENTS_BEFORE_SELECTION, grouping.getViewStudentsBeforeSelection()); + return mapping.findForward(GroupingAction.CHOOSE_GROUP); + } + } \ No newline at end of file Index: lams_learning/web/grouping/choose.jsp =================================================================== diff -u -rc209be8131f22f6fe37bd8d6c14b56425a78b766 -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 --- lams_learning/web/grouping/choose.jsp (.../choose.jsp) (revision c209be8131f22f6fe37bd8d6c14b56425a78b766) +++ lams_learning/web/grouping/choose.jsp (.../choose.jsp) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) @@ -48,10 +48,12 @@ - -
    -
    -   + + +
    +
    +   +