Index: lams_build/lib/lams/lams-central.jar =================================================================== diff -u -rbe67c75d689af8e546c029f1f7b3973c6a36fdd2 -r542b83631b403e37429fce3bb928f2800c5cd9b8 Binary files differ Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -rbe67c75d689af8e546c029f1f7b3973c6a36fdd2 -r542b83631b403e37429fce3bb928f2800c5cd9b8 Binary files differ Index: lams_central/.classpath =================================================================== diff -u -r3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_central/.classpath (.../.classpath) (revision 3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23) +++ lams_central/.classpath (.../.classpath) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -11,7 +11,5 @@ - - Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -rd02ece68fd7e5bd6ca301c92d9f41a6580a6e5ed -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision d02ece68fd7e5bd6ca301c92d9f41a6580a6e5ed) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -92,2077 +92,1792 @@ * @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. * */ public class ObjectExtractor implements IObjectExtractor { - private static final Integer DEFAULT_COORD = new Integer(10); // default - // coordinate - // used if - // the entry - // from - // Flash is - // 0 or - // less. + private static final Integer DEFAULT_COORD = new Integer(10); // default + // coordinate + // used if + // the entry + // from + // Flash is + // 0 or + // less. - protected IBaseDAO baseDAO = null; - protected ILearningDesignDAO learningDesignDAO = null; - protected IActivityDAO activityDAO = null; - protected ICompetenceDAO competenceDAO = null; - protected ICompetenceMappingDAO competenceMappingDAO = null; - protected ITransitionDAO transitionDAO = null; - protected ILearningLibraryDAO learningLibraryDAO = null; - protected ILicenseDAO licenseDAO = null; - protected IGroupingDAO groupingDAO = null; - protected IToolDAO toolDAO = null; - protected ISystemToolDAO systemToolDAO = null; - protected IGroupDAO groupDAO = null; - protected IToolSessionDAO toolSessionDAO = null; - protected IBranchActivityEntryDAO branchActivityEntryDAO = null; + protected IBaseDAO baseDAO = null; + protected ILearningDesignDAO learningDesignDAO = null; + protected IActivityDAO activityDAO = null; + protected ICompetenceDAO competenceDAO = null; + protected ICompetenceMappingDAO competenceMappingDAO = null; + protected ITransitionDAO transitionDAO = null; + protected ILearningLibraryDAO learningLibraryDAO = null; + protected ILicenseDAO licenseDAO = null; + protected IGroupingDAO groupingDAO = null; + protected IToolDAO toolDAO = null; + protected ISystemToolDAO systemToolDAO = null; + protected IGroupDAO groupDAO = null; + protected IToolSessionDAO toolSessionDAO = null; + protected IBranchActivityEntryDAO branchActivityEntryDAO = null; - private Integer mode = null; + private Integer mode = null; - /* - * The newActivityMap is a local copy of all the current activities. This - * will include the "top level" activities and subactivities. It is used to - * "crossreference" activities as we go, without having to repull them from - * the database. The keys are the UIIDs of the activities, not the IDs. It - * is important that the values in this map are the Activity objects related - * to the Hibernate session as they are updated by the parseTransitions - * code. - */ - protected HashMap newActivityMap = new HashMap(); - /* - * Record the tool sessions and activities as we go for edit on fly. This is - * needed in case we delete any. Cannot get them at the end as Hibernate - * tries to store the activities before getting the tool sessions, and this - * fails due to a foriegn key error. Its the foriegn key error that we are - * trying to avoid! - */ - protected HashMap> toolSessionMap = new HashMap>(); // Activity - // UIID - // -> - // ToolSession - /* - * Used for easy access (rather than going back to the db) and makes it - * easier to clean them up at the end - they can't be deleted easily via the - * cascades as we don't get a list of deleted entries sent back from the - * client! We would end up with mappings still attached to a sequence - * activity that shouldn't be there! Not done as a map as we sometimes will - * check via UIID, sometimes by ID - */ - protected List oldbranchActivityEntryList = new ArrayList(); + /* + * The newActivityMap is a local copy of all the current activities. This will include the "top level" activities + * and subactivities. It is used to "crossreference" activities as we go, without having to repull them from the + * database. The keys are the UIIDs of the activities, not the IDs. It is important that the values in this map are + * the Activity objects related to the Hibernate session as they are updated by the parseTransitions code. + */ + protected HashMap newActivityMap = new HashMap(); + /* + * Record the tool sessions and activities as we go for edit on fly. This is needed in case we delete any. Cannot + * get them at the end as Hibernate tries to store the activities before getting the tool sessions, and this fails + * due to a foriegn key error. Its the foriegn key error that we are trying to avoid! + */ + protected HashMap> toolSessionMap = new HashMap>(); // Activity + // UIID + // -> + // ToolSession + /* + * Used for easy access (rather than going back to the db) and makes it easier to clean them up at the end - they + * can't be deleted easily via the cascades as we don't get a list of deleted entries sent back from the client! We + * would end up with mappings still attached to a sequence activity that shouldn't be there! Not done as a map as we + * sometimes will check via UIID, sometimes by ID + */ + protected List oldbranchActivityEntryList = new ArrayList(); - protected HashMap oldActivityMap = new HashMap(); // Activity - // UIID - // -> - // Activity - /* cache of groupings - too hard to get them from the db */ - protected HashMap groupings = new HashMap(); - protected HashMap groups = new HashMap(); - protected HashMap branchEntries = new HashMap(); - protected HashMap defaultActivityMap = new HashMap(); - /* - * can't delete as we go as they are linked to other items and have no way - * of knowing from the packet which ones will need to be deleted, so start - * off assuming all need to be deleted and remove the ones we want to keep. - */ - protected HashMap groupingsToDelete = new HashMap(); - protected LearningDesign learningDesign = null; - protected Date modificationDate = null; - /* cache of system tools so we aren't going back to the db all the time */ - protected HashMap systemTools = new HashMap(); + protected HashMap oldActivityMap = new HashMap(); // Activity + // UIID + // -> + // Activity + /* cache of groupings - too hard to get them from the db */ + protected HashMap groupings = new HashMap(); + protected HashMap groups = new HashMap(); + protected HashMap branchEntries = new HashMap(); + protected HashMap defaultActivityMap = new HashMap(); + /* + * can't delete as we go as they are linked to other items and have no way of knowing from the packet which ones + * will need to be deleted, so start off assuming all need to be deleted and remove the ones we want to keep. + */ + protected HashMap groupingsToDelete = new HashMap(); + protected LearningDesign learningDesign = null; + protected Date modificationDate = null; + /* cache of system tools so we aren't going back to the db all the time */ + protected HashMap systemTools = new HashMap(); - protected Logger log = Logger.getLogger(ObjectExtractor.class); + protected Logger log = Logger.getLogger(ObjectExtractor.class); - /** Constructor to be used if Spring method injection is used */ - public ObjectExtractor() { - modificationDate = new Date(); - } + /** Constructor to be used if Spring method injection is used */ + public ObjectExtractor() { + modificationDate = new Date(); + } - /** Constructor to be used if Spring method injection is not used */ - public ObjectExtractor(IBaseDAO baseDAO, - ILearningDesignDAO learningDesignDAO, IActivityDAO activityDAO, - ILearningLibraryDAO learningLibraryDAO, ILicenseDAO licenseDAO, - IGroupingDAO groupingDAO, IToolDAO toolDAO, - ISystemToolDAO systemToolDAO, IGroupDAO groupDAO, - ITransitionDAO transitionDAO, IToolSessionDAO toolSessionDAO) { - this.baseDAO = baseDAO; - this.learningDesignDAO = learningDesignDAO; - this.activityDAO = activityDAO; - this.learningLibraryDAO = learningLibraryDAO; - this.licenseDAO = licenseDAO; - this.groupingDAO = groupingDAO; - this.toolDAO = toolDAO; - this.systemToolDAO = systemToolDAO; - this.groupDAO = groupDAO; - this.transitionDAO = transitionDAO; - this.toolSessionDAO = toolSessionDAO; - modificationDate = new Date(); - } + /** Constructor to be used if Spring method injection is not used */ + public ObjectExtractor(IBaseDAO baseDAO, ILearningDesignDAO learningDesignDAO, IActivityDAO activityDAO, + ILearningLibraryDAO learningLibraryDAO, ILicenseDAO licenseDAO, IGroupingDAO groupingDAO, IToolDAO toolDAO, + ISystemToolDAO systemToolDAO, IGroupDAO groupDAO, ITransitionDAO transitionDAO, + IToolSessionDAO toolSessionDAO) { + this.baseDAO = baseDAO; + this.learningDesignDAO = learningDesignDAO; + this.activityDAO = activityDAO; + this.learningLibraryDAO = learningLibraryDAO; + this.licenseDAO = licenseDAO; + this.groupingDAO = groupingDAO; + this.toolDAO = toolDAO; + this.systemToolDAO = systemToolDAO; + this.groupDAO = groupDAO; + this.transitionDAO = transitionDAO; + this.toolSessionDAO = toolSessionDAO; + modificationDate = new Date(); + } - /** Spring injection methods */ - public IActivityDAO getActivityDAO() { - return activityDAO; - } + /** Spring injection methods */ + public IActivityDAO getActivityDAO() { + return activityDAO; + } - public void setActivityDAO(IActivityDAO activityDAO) { - this.activityDAO = activityDAO; - } + public void setActivityDAO(IActivityDAO activityDAO) { + this.activityDAO = activityDAO; + } - public ICompetenceDAO getCompetenceDAO() { - return competenceDAO; - } + public ICompetenceDAO getCompetenceDAO() { + return competenceDAO; + } - public void setCompetenceDAO(ICompetenceDAO competenceDAO) { - this.competenceDAO = competenceDAO; - } + public void setCompetenceDAO(ICompetenceDAO competenceDAO) { + this.competenceDAO = competenceDAO; + } - public ICompetenceMappingDAO getCompetenceMappingDAO() { - return competenceMappingDAO; - } + public ICompetenceMappingDAO getCompetenceMappingDAO() { + return competenceMappingDAO; + } - public void setCompetenceMappingDAO( - ICompetenceMappingDAO competenceMappingDAO) { - this.competenceMappingDAO = competenceMappingDAO; - } + public void setCompetenceMappingDAO(ICompetenceMappingDAO competenceMappingDAO) { + this.competenceMappingDAO = competenceMappingDAO; + } - public IGroupDAO getGroupDAO() { - return groupDAO; - } + public IGroupDAO getGroupDAO() { + return groupDAO; + } - public void setGroupDAO(IGroupDAO groupDAO) { - this.groupDAO = groupDAO; - } + public void setGroupDAO(IGroupDAO groupDAO) { + this.groupDAO = groupDAO; + } - public IGroupingDAO getGroupingDAO() { - return groupingDAO; - } + public IGroupingDAO getGroupingDAO() { + return groupingDAO; + } - public void setGroupingDAO(IGroupingDAO groupingDAO) { - this.groupingDAO = groupingDAO; - } + public void setGroupingDAO(IGroupingDAO groupingDAO) { + this.groupingDAO = groupingDAO; + } - public ILearningDesignDAO getLearningDesignDAO() { - return learningDesignDAO; - } + public ILearningDesignDAO getLearningDesignDAO() { + return learningDesignDAO; + } - public void setLearningDesignDAO(ILearningDesignDAO learningDesignDAO) { - this.learningDesignDAO = learningDesignDAO; - } + public void setLearningDesignDAO(ILearningDesignDAO learningDesignDAO) { + this.learningDesignDAO = learningDesignDAO; + } - public ILearningLibraryDAO getLearningLibraryDAO() { - return learningLibraryDAO; - } + public ILearningLibraryDAO getLearningLibraryDAO() { + return learningLibraryDAO; + } - public void setLearningLibraryDAO(ILearningLibraryDAO learningLibraryDAO) { - this.learningLibraryDAO = learningLibraryDAO; - } + public void setLearningLibraryDAO(ILearningLibraryDAO learningLibraryDAO) { + this.learningLibraryDAO = learningLibraryDAO; + } - public ILicenseDAO getLicenseDAO() { - return licenseDAO; - } + public ILicenseDAO getLicenseDAO() { + return licenseDAO; + } - public void setLicenseDAO(ILicenseDAO licenseDAO) { - this.licenseDAO = licenseDAO; - } + public void setLicenseDAO(ILicenseDAO licenseDAO) { + this.licenseDAO = licenseDAO; + } - public IToolSessionDAO getToolSessionDAODAO() { - return toolSessionDAO; - } + public IToolSessionDAO getToolSessionDAODAO() { + return toolSessionDAO; + } - public void setToolSessionDAO(IToolSessionDAO toolSessionDAO) { - this.toolSessionDAO = toolSessionDAO; - } + public void setToolSessionDAO(IToolSessionDAO toolSessionDAO) { + this.toolSessionDAO = toolSessionDAO; + } - public HashMap getNewActivityMap() { - return newActivityMap; - } + public HashMap getNewActivityMap() { + return newActivityMap; + } - public void setNewActivityMap(HashMap newActivityMap) { - this.newActivityMap = newActivityMap; - } + public void setNewActivityMap(HashMap newActivityMap) { + this.newActivityMap = newActivityMap; + } - public IToolDAO getToolDAO() { - return toolDAO; - } + public IToolDAO getToolDAO() { + return toolDAO; + } - public void setToolDAO(IToolDAO toolDAO) { - this.toolDAO = toolDAO; - } + public void setToolDAO(IToolDAO toolDAO) { + this.toolDAO = toolDAO; + } - public ISystemToolDAO getSystemToolDAO() { - return systemToolDAO; - } + public ISystemToolDAO getSystemToolDAO() { + return systemToolDAO; + } - public void setSystemToolDAO(ISystemToolDAO systemToolDAO) { - this.systemToolDAO = systemToolDAO; - } + public void setSystemToolDAO(ISystemToolDAO systemToolDAO) { + this.systemToolDAO = systemToolDAO; + } - public ITransitionDAO getTransitionDAO() { - return transitionDAO; - } + public ITransitionDAO getTransitionDAO() { + return transitionDAO; + } - public void setTransitionDAO(ITransitionDAO transitionDAO) { - this.transitionDAO = transitionDAO; - } + public void setTransitionDAO(ITransitionDAO transitionDAO) { + this.transitionDAO = transitionDAO; + } - public IBaseDAO getBaseDAO() { - return baseDAO; - } + public IBaseDAO getBaseDAO() { + return baseDAO; + } - public void setBaseDAO(IBaseDAO baseDAO) { - this.baseDAO = baseDAO; - } + public void setBaseDAO(IBaseDAO baseDAO) { + this.baseDAO = baseDAO; + } - public IBranchActivityEntryDAO getBranchActivityEntryDAO() { - return branchActivityEntryDAO; - } + public IBranchActivityEntryDAO getBranchActivityEntryDAO() { + return branchActivityEntryDAO; + } - public void setBranchActivityEntryDAO( - IBranchActivityEntryDAO branchActivityEntryDAO) { - this.branchActivityEntryDAO = branchActivityEntryDAO; - } + public void setBranchActivityEntryDAO(IBranchActivityEntryDAO branchActivityEntryDAO) { + this.branchActivityEntryDAO = branchActivityEntryDAO; + } - /* - * (non-Javadoc) - * - * @see org.lamsfoundation.lams.authoring.IObjectExtractor#extractSaveLearningDesign(java.util.Hashtable) - */ - public LearningDesign extractSaveLearningDesign(Hashtable table, - LearningDesign existingLearningDesign, - WorkspaceFolder workspaceFolder, User user) - throws WDDXProcessorConversionException, ObjectExtractorException { + /* + * (non-Javadoc) + * + * @see org.lamsfoundation.lams.authoring.IObjectExtractor#extractSaveLearningDesign(java.util.Hashtable) + */ + public LearningDesign extractSaveLearningDesign(Hashtable table, LearningDesign existingLearningDesign, + WorkspaceFolder workspaceFolder, User user) throws WDDXProcessorConversionException, + ObjectExtractorException { - // if the learningDesign already exists, update it, otherwise create a - // new one. - learningDesign = existingLearningDesign != null ? existingLearningDesign - : new LearningDesign(); + // if the learningDesign already exists, update it, otherwise create a + // new one. + learningDesign = existingLearningDesign != null ? existingLearningDesign : new LearningDesign(); - // Check the copy type. Can only update it if it is COPY_TYPE_NONE (ie - // authoring copy) - Integer copyTypeID = WDDXProcessor.convertToInteger(table, - WDDXTAGS.COPY_TYPE); - if (copyTypeID == null) { - copyTypeID = LearningDesign.COPY_TYPE_NONE; - } - if (learningDesign != null && learningDesign.getCopyTypeID() != null - && !learningDesign.getCopyTypeID().equals(copyTypeID) - && !learningDesign.getEditOverrideLock()) { - throw new ObjectExtractorException( - "Unable to save learning design. Cannot change copy type on existing design."); - } - if (!copyTypeID.equals(LearningDesign.COPY_TYPE_NONE) - && !learningDesign.getEditOverrideLock()) { - throw new ObjectExtractorException( - "Unable to save learning design. Learning design is read-only"); - } - learningDesign.setCopyTypeID(copyTypeID); + // Check the copy type. Can only update it if it is COPY_TYPE_NONE (ie + // authoring copy) + Integer copyTypeID = WDDXProcessor.convertToInteger(table, WDDXTAGS.COPY_TYPE); + if (copyTypeID == null) { + copyTypeID = LearningDesign.COPY_TYPE_NONE; + } + if (learningDesign != null && learningDesign.getCopyTypeID() != null + && !learningDesign.getCopyTypeID().equals(copyTypeID) && !learningDesign.getEditOverrideLock()) { + throw new ObjectExtractorException( + "Unable to save learning design. Cannot change copy type on existing design."); + } + if (!copyTypeID.equals(LearningDesign.COPY_TYPE_NONE) && !learningDesign.getEditOverrideLock()) { + throw new ObjectExtractorException("Unable to save learning design. Learning design is read-only"); + } + learningDesign.setCopyTypeID(copyTypeID); - learningDesign.setWorkspaceFolder(workspaceFolder); - learningDesign.setUser(user); + learningDesign.setWorkspaceFolder(workspaceFolder); + learningDesign.setUser(user); - // Pull out all the existing groups. there isn't an easy way to pull - // them out of the db requires an outer join across - // three objects (learning design -> grouping activity -> grouping) so - // put both the existing ones and the new ones - // here for reference later. - initialiseGroupings(); + // Pull out all the existing groups. there isn't an easy way to pull + // them out of the db requires an outer join across + // three objects (learning design -> grouping activity -> grouping) so + // put both the existing ones and the new ones + // here for reference later. + initialiseGroupings(); - // Branch activity mappings are indirectly accessible via sequence - // activities or groupings. Have a separate list - // to make them easier to delete unwanted ones later. - intialiseBranchActivityMappings(); + // Branch activity mappings are indirectly accessible via sequence + // activities or groupings. Have a separate list + // to make them easier to delete unwanted ones later. + intialiseBranchActivityMappings(); - // get a mapping of all the existing activities and their tool sessions, - // in case we need to delete some tool sessions later. - initialiseToolSessionMap(learningDesign); + // get a mapping of all the existing activities and their tool sessions, + // in case we need to delete some tool sessions later. + initialiseToolSessionMap(learningDesign); - // get the core learning design stuff - default to invalid - learningDesign.setValidDesign(Boolean.FALSE); - if (keyExists(table, WDDXTAGS.LEARNING_DESIGN_UIID)) { - learningDesign.setLearningDesignUIID(WDDXProcessor - .convertToInteger(table, WDDXTAGS.LEARNING_DESIGN_UIID)); - } - if (keyExists(table, WDDXTAGS.DESCRIPTION)) { - learningDesign.setDescription(WDDXProcessor.convertToString(table, - WDDXTAGS.DESCRIPTION)); - } - if (keyExists(table, WDDXTAGS.TITLE)) { - learningDesign.setTitle(WDDXProcessor.convertToString(table, - WDDXTAGS.TITLE)); - } - if (keyExists(table, WDDXTAGS.MAX_ID)) { - learningDesign.setMaxID(WDDXProcessor.convertToInteger(table, - WDDXTAGS.MAX_ID)); - } - if (keyExists(table, WDDXTAGS.VALID_DESIGN)) { - learningDesign.setValidDesign(WDDXProcessor.convertToBoolean(table, - WDDXTAGS.VALID_DESIGN)); - } - if (keyExists(table, WDDXTAGS.READ_ONLY)) { - learningDesign.setReadOnly(WDDXProcessor.convertToBoolean(table, - WDDXTAGS.READ_ONLY)); - } - if (keyExists(table, WDDXTAGS.EDIT_OVERRIDE_LOCK)) { - learningDesign.setEditOverrideLock(WDDXProcessor.convertToBoolean( - table, WDDXTAGS.EDIT_OVERRIDE_LOCK)); - } - if (keyExists(table, WDDXTAGS.DATE_READ_ONLY)) { - learningDesign.setDateReadOnly(WDDXProcessor.convertToDate(table, - WDDXTAGS.DATE_READ_ONLY)); - } - if (keyExists(table, WDDXTAGS.OFFLINE_INSTRUCTIONS)) { - learningDesign.setOfflineInstructions(WDDXProcessor - .convertToString(table, WDDXTAGS.OFFLINE_INSTRUCTIONS)); - } - if (keyExists(table, WDDXTAGS.ONLINE_INSTRUCTIONS)) { - learningDesign.setOnlineInstructions(WDDXProcessor.convertToString( - table, WDDXTAGS.ONLINE_INSTRUCTIONS)); - } - if (keyExists(table, WDDXTAGS.HELP_TEXT)) { - learningDesign.setHelpText(WDDXProcessor.convertToString(table, - WDDXTAGS.HELP_TEXT)); - } - // don't receive version from flash anymore(it was hardcoded). Get it - // from lams configuration database. - learningDesign.setVersion(Configuration - .get(ConfigurationKeys.SERVER_VERSION_NUMBER)); + // get the core learning design stuff - default to invalid + learningDesign.setValidDesign(Boolean.FALSE); + if (keyExists(table, WDDXTAGS.LEARNING_DESIGN_UIID)) { + learningDesign.setLearningDesignUIID(WDDXProcessor.convertToInteger(table, WDDXTAGS.LEARNING_DESIGN_UIID)); + } + if (keyExists(table, WDDXTAGS.DESCRIPTION)) { + learningDesign.setDescription(WDDXProcessor.convertToString(table, WDDXTAGS.DESCRIPTION)); + } + if (keyExists(table, WDDXTAGS.TITLE)) { + learningDesign.setTitle(WDDXProcessor.convertToString(table, WDDXTAGS.TITLE)); + } + if (keyExists(table, WDDXTAGS.MAX_ID)) { + learningDesign.setMaxID(WDDXProcessor.convertToInteger(table, WDDXTAGS.MAX_ID)); + } + if (keyExists(table, WDDXTAGS.VALID_DESIGN)) { + learningDesign.setValidDesign(WDDXProcessor.convertToBoolean(table, WDDXTAGS.VALID_DESIGN)); + } + if (keyExists(table, WDDXTAGS.READ_ONLY)) { + learningDesign.setReadOnly(WDDXProcessor.convertToBoolean(table, WDDXTAGS.READ_ONLY)); + } + if (keyExists(table, WDDXTAGS.EDIT_OVERRIDE_LOCK)) { + learningDesign.setEditOverrideLock(WDDXProcessor.convertToBoolean(table, WDDXTAGS.EDIT_OVERRIDE_LOCK)); + } + if (keyExists(table, WDDXTAGS.DATE_READ_ONLY)) { + learningDesign.setDateReadOnly(WDDXProcessor.convertToDate(table, WDDXTAGS.DATE_READ_ONLY)); + } + if (keyExists(table, WDDXTAGS.OFFLINE_INSTRUCTIONS)) { + learningDesign.setOfflineInstructions(WDDXProcessor.convertToString(table, WDDXTAGS.OFFLINE_INSTRUCTIONS)); + } + if (keyExists(table, WDDXTAGS.ONLINE_INSTRUCTIONS)) { + learningDesign.setOnlineInstructions(WDDXProcessor.convertToString(table, WDDXTAGS.ONLINE_INSTRUCTIONS)); + } + if (keyExists(table, WDDXTAGS.HELP_TEXT)) { + learningDesign.setHelpText(WDDXProcessor.convertToString(table, WDDXTAGS.HELP_TEXT)); + } + // don't receive version from flash anymore(it was hardcoded). Get it + // from lams configuration database. + learningDesign.setVersion(Configuration.get(ConfigurationKeys.SERVER_VERSION_NUMBER)); - if (keyExists(table, WDDXTAGS.DURATION)) { - learningDesign.setDuration(WDDXProcessor.convertToLong(table, - WDDXTAGS.DURATION)); - } + if (keyExists(table, WDDXTAGS.DURATION)) { + learningDesign.setDuration(WDDXProcessor.convertToLong(table, WDDXTAGS.DURATION)); + } - if (keyExists(table, WDDXTAGS.DURATION)) { - learningDesign.setDuration(WDDXProcessor.convertToLong(table, - WDDXTAGS.DURATION)); - } + if (keyExists(table, WDDXTAGS.DURATION)) { + learningDesign.setDuration(WDDXProcessor.convertToLong(table, WDDXTAGS.DURATION)); + } - if (keyExists(table, WDDXTAGS.CONTENT_FOLDER_ID)) { - learningDesign.setContentFolderID(WDDXProcessor.convertToString( - table, WDDXTAGS.CONTENT_FOLDER_ID)); - } + if (keyExists(table, WDDXTAGS.CONTENT_FOLDER_ID)) { + learningDesign.setContentFolderID(WDDXProcessor.convertToString(table, WDDXTAGS.CONTENT_FOLDER_ID)); + } - if (keyExists(table, WDDXTAGS.SAVE_MODE)) { - mode = WDDXProcessor.convertToInteger(table, WDDXTAGS.SAVE_MODE); - } + if (keyExists(table, WDDXTAGS.SAVE_MODE)) { + mode = WDDXProcessor.convertToInteger(table, WDDXTAGS.SAVE_MODE); + } - // Set creation date and modification date based on the server timezone, - // not the client. - if (learningDesign.getCreateDateTime() == null) { - learningDesign.setCreateDateTime(modificationDate); - } - learningDesign.setLastModifiedDateTime(modificationDate); + // Set creation date and modification date based on the server timezone, + // not the client. + if (learningDesign.getCreateDateTime() == null) { + learningDesign.setCreateDateTime(modificationDate); + } + learningDesign.setLastModifiedDateTime(modificationDate); - if (keyExists(table, WDDXTAGS.LICENCE_ID)) { - Long licenseID = WDDXProcessor.convertToLong(table, - WDDXTAGS.LICENCE_ID); - if (licenseID != null) { - License license = licenseDAO.getLicenseByID(licenseID); - learningDesign.setLicense(license); - } - else { - learningDesign.setLicense(null); // special null value set - } - } - if (keyExists(table, WDDXTAGS.LICENSE_TEXT)) { - learningDesign.setLicenseText(WDDXProcessor.convertToString(table, - WDDXTAGS.LICENSE_TEXT)); - } + if (keyExists(table, WDDXTAGS.LICENCE_ID)) { + Long licenseID = WDDXProcessor.convertToLong(table, WDDXTAGS.LICENCE_ID); + if (licenseID != null) { + License license = licenseDAO.getLicenseByID(licenseID); + learningDesign.setLicense(license); + } else { + learningDesign.setLicense(null); // special null value set + } + } + if (keyExists(table, WDDXTAGS.LICENSE_TEXT)) { + learningDesign.setLicenseText(WDDXProcessor.convertToString(table, WDDXTAGS.LICENSE_TEXT)); + } - if (keyExists(table, WDDXTAGS.ORIGINAL_DESIGN_ID)) { - Long parentLearningDesignID = WDDXProcessor.convertToLong(table, - WDDXTAGS.ORIGINAL_DESIGN_ID); - if (parentLearningDesignID != null) { - LearningDesign parent = learningDesignDAO - .getLearningDesignById(parentLearningDesignID); - learningDesign.setOriginalLearningDesign(parent); - } - else { - learningDesign.setOriginalLearningDesign(null); - } - } + if (keyExists(table, WDDXTAGS.ORIGINAL_DESIGN_ID)) { + Long parentLearningDesignID = WDDXProcessor.convertToLong(table, WDDXTAGS.ORIGINAL_DESIGN_ID); + if (parentLearningDesignID != null) { + LearningDesign parent = learningDesignDAO.getLearningDesignById(parentLearningDesignID); + learningDesign.setOriginalLearningDesign(parent); + } else { + learningDesign.setOriginalLearningDesign(null); + } + } - learningDesignDAO.insertOrUpdate(learningDesign); + learningDesignDAO.insertOrUpdate(learningDesign); - // now process the "parts" of the learning design - parseCompetences((Vector) table.get(WDDXTAGS.COMPETENCES), - learningDesign); - parseGroupings((Vector) table.get(WDDXTAGS.GROUPINGS)); - parseActivities((Vector) table.get(WDDXTAGS.ACTIVITIES)); - parseActivitiesToMatchUpParentandInputActivities((Vector) table - .get(WDDXTAGS.ACTIVITIES)); - parseTransitions((Vector) table.get(WDDXTAGS.TRANSITIONS)); - parseBranchMappings((Vector) table.get(WDDXTAGS.BRANCH_MAPPINGS)); - parseCompetenceMappings((Vector) table.get(WDDXTAGS.ACTIVITIES)); - progressDefaultChildActivities(); + // now process the "parts" of the learning design + parseCompetences((Vector) table.get(WDDXTAGS.COMPETENCES), learningDesign); + parseGroupings((Vector) table.get(WDDXTAGS.GROUPINGS)); + parseActivities((Vector) table.get(WDDXTAGS.ACTIVITIES)); + parseActivitiesToMatchUpParentandInputActivities((Vector) table.get(WDDXTAGS.ACTIVITIES)); + parseTransitions((Vector) table.get(WDDXTAGS.TRANSITIONS)); + parseBranchMappings((Vector) table.get(WDDXTAGS.BRANCH_MAPPINGS)); + parseCompetenceMappings((Vector) table.get(WDDXTAGS.ACTIVITIES)); + progressDefaultChildActivities(); - learningDesign - .setFirstActivity(learningDesign.calculateFirstActivity()); - learningDesignDAO.insertOrUpdate(learningDesign); - deleteUnwantedGroupings(); - deleteUnwantedToolSessions(learningDesign); + learningDesign.setFirstActivity(learningDesign.calculateFirstActivity()); + learningDesignDAO.insertOrUpdate(learningDesign); - return learningDesign; - } + deleteUnwantedGroupings(); + deleteUnwantedToolSessions(learningDesign); - /** - * 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 - */ - private void progressDefaultChildActivities() - throws WDDXProcessorConversionException { + return learningDesign; + } - if (defaultActivityMap.size() > 0) { - for (Integer defaultChildUIID : defaultActivityMap.keySet()) { - ComplexActivity complex = defaultActivityMap - .get(defaultChildUIID); - Activity defaultActivity = newActivityMap.get(defaultChildUIID); - if (defaultActivity == null) { - String msg = "Unable to find the default child activity (" - + defaultChildUIID + ") for the activity (" - + complex - + ") referred to in First Child to Sequence map."; - throw new WDDXProcessorConversionException(msg); - } - else { - complex.setDefaultActivity(defaultActivity); + /** + * 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 + */ + private void progressDefaultChildActivities() throws WDDXProcessorConversionException { - // fix up the order ids for SequenceActivities - if (complex.isSequenceActivity()) { - Set unprocessedChildren = new TreeSet( - new ActivityOrderComparator()); - unprocessedChildren.addAll(complex.getActivities()); + if (defaultActivityMap.size() > 0) { + for (Integer defaultChildUIID : defaultActivityMap.keySet()) { + ComplexActivity complex = defaultActivityMap.get(defaultChildUIID); + Activity defaultActivity = newActivityMap.get(defaultChildUIID); + if (defaultActivity == null) { + String msg = "Unable to find the default child activity (" + defaultChildUIID + + ") for the activity (" + complex + ") referred to in First Child to Sequence map."; + throw new WDDXProcessorConversionException(msg); + } else { + complex.setDefaultActivity(defaultActivity); - unprocessedChildren.remove(defaultActivity); - defaultActivity.setOrderId(1); + // fix up the order ids for SequenceActivities + if (complex.isSequenceActivity()) { + Set unprocessedChildren = new TreeSet(new ActivityOrderComparator()); + unprocessedChildren.addAll(complex.getActivities()); - int nextOrderId = 2; - Activity nextActivity = defaultActivity - .getTransitionFrom() != null ? defaultActivity - .getTransitionFrom().getToActivity() : null; - while (nextActivity != null) { - boolean removed = unprocessedChildren - .remove(nextActivity); - if (!removed) { - log - .error("Next activity should be a child of the current sequence, but it isn't. Could we have a loop in the transitions? Aborting the ordering of ids based on transitions. Sequence activity " - + complex - + " next activity " - + nextActivity); - break; - } - nextActivity.setOrderId(nextOrderId++); - nextActivity = nextActivity.getTransitionFrom() != null ? nextActivity - .getTransitionFrom().getToActivity() - : null; - } + unprocessedChildren.remove(defaultActivity); + defaultActivity.setOrderId(1); - if (unprocessedChildren.size() > 0) { - Iterator iter = unprocessedChildren.iterator(); - while (iter.hasNext()) { - nextActivity = (Activity) iter.next(); - nextActivity.setOrderId(nextOrderId++); - } - } - } - } + int nextOrderId = 2; + Activity nextActivity = defaultActivity.getTransitionFrom() != null ? defaultActivity + .getTransitionFrom().getToActivity() : null; + while (nextActivity != null) { + boolean removed = unprocessedChildren.remove(nextActivity); + if (!removed) { + log + .error("Next activity should be a child of the current sequence, but it isn't. Could we have a loop in the transitions? Aborting the ordering of ids based on transitions. Sequence activity " + + complex + " next activity " + nextActivity); + break; + } + nextActivity.setOrderId(nextOrderId++); + nextActivity = nextActivity.getTransitionFrom() != null ? nextActivity.getTransitionFrom() + .getToActivity() : null; } + if (unprocessedChildren.size() > 0) { + Iterator iter = unprocessedChildren.iterator(); + while (iter.hasNext()) { + nextActivity = (Activity) iter.next(); + nextActivity.setOrderId(nextOrderId++); + } + } + } } - } + } - /** - * 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()); - Iterator iter = dbGroupings.iterator(); - while (iter.hasNext()) { - Grouping grouping = (Grouping) iter.next(); - groupings.put(grouping.getGroupingUIID(), grouping); - groupingsToDelete.put(grouping.getGroupingUIID(), grouping); - } } + } - private void intialiseBranchActivityMappings() { - oldbranchActivityEntryList = branchActivityEntryDAO - .getEntriesByLearningDesign(learningDesign - .getLearningDesignId()); + /** + * 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()); + Iterator iter = dbGroupings.iterator(); + while (iter.hasNext()) { + Grouping grouping = (Grouping) iter.next(); + groupings.put(grouping.getGroupingUIID(), grouping); + groupingsToDelete.put(grouping.getGroupingUIID(), grouping); } + } - /** - * 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) { - if (learningDesign.getEditOverrideLock() - && learningDesign.getEditOverrideUser() != null) { - Iterator iter = learningDesign.getActivities().iterator(); - while (iter.hasNext()) { - Activity activity = (Activity) iter.next(); - oldActivityMap.put(activity.getActivityUIID(), activity); - List toolSessions = toolSessionDAO - .getToolSessionByActivity(activity); - if (toolSessions != null && toolSessions.size() > 0) { - toolSessionMap - .put(activity.getActivityUIID(), toolSessions); - } - } + private void intialiseBranchActivityMappings() { + oldbranchActivityEntryList = branchActivityEntryDAO.getEntriesByLearningDesign(learningDesign + .getLearningDesignId()); + } + + /** + * 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) { + if (learningDesign.getEditOverrideLock() && learningDesign.getEditOverrideUser() != null) { + Iterator iter = learningDesign.getActivities().iterator(); + while (iter.hasNext()) { + Activity activity = (Activity) iter.next(); + oldActivityMap.put(activity.getActivityUIID(), activity); + List toolSessions = toolSessionDAO.getToolSessionByActivity(activity); + if (toolSessions != null && toolSessions.size() > 0) { + toolSessionMap.put(activity.getActivityUIID(), toolSessions); } + } } + } - /** Delete the old unneeded groupings. Won't be done via a cascade */ - private void deleteUnwantedGroupings() { - for (Grouping grouping : groupingsToDelete.values()) { - groupingDAO.delete(grouping); - } + /** Delete the old unneeded groupings. Won't be done via a cascade */ + private void deleteUnwantedGroupings() { + for (Grouping grouping : groupingsToDelete.values()) { + groupingDAO.delete(grouping); } + } - /** - * 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) { + /** + * 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) { - for (Integer uiid : toolSessionMap.keySet()) { - if (!newActivityMap.containsKey(uiid)) { - List toolSessions = toolSessionMap.get(uiid); - if (toolSessions != null) { + for (Integer uiid : toolSessionMap.keySet()) { + if (!newActivityMap.containsKey(uiid)) { + List toolSessions = toolSessionMap.get(uiid); + if (toolSessions != null) { - Activity activity = oldActivityMap.get(uiid); - if (toolSessions.size() > 1) { - throw new ObjectExtractorException( - "More than one tool session exists for activity " - + activity.getTitle() - + " (" - + uiid - + ") but this shouldn't be possible. Cannot delete this tool session so editing is not allowed!"); - } - else if (toolSessions.size() == 1) { + Activity activity = oldActivityMap.get(uiid); + if (toolSessions.size() > 1) { + throw new ObjectExtractorException( + "More than one tool session exists for activity " + + activity.getTitle() + + " (" + + uiid + + ") but this shouldn't be possible. Cannot delete this tool session so editing is not allowed!"); + } else if (toolSessions.size() == 1) { - ToolSession toolSession = (ToolSession) toolSessions - .get(0); - if (activity.isGroupingActivity()) { - throw new ObjectExtractorException( - "Activity " - + activity.getTitle() - + " (" - + activity.getActivityUIID() - + ") has a tool session but it is grouped. Cannot delete this tool session so editing is not allowed!"); - } + ToolSession toolSession = (ToolSession) toolSessions.get(0); + if (activity.isGroupingActivity()) { + throw new ObjectExtractorException( + "Activity " + + activity.getTitle() + + " (" + + activity.getActivityUIID() + + ") has a tool session but it is grouped. Cannot delete this tool session so editing is not allowed!"); + } - // all okay, do ahead and delete the tool session - if (log.isDebugEnabled()) { - log.debug("Removing tool session for activity " - + activity.getTitle() + " (" - + activity.getActivityUIID() + ")"); - } + // all okay, do ahead and delete the tool session + if (log.isDebugEnabled()) { + log.debug("Removing tool session for activity " + activity.getTitle() + " (" + + activity.getActivityUIID() + ")"); + } - toolSessionDAO.removeToolSession(toolSession); - } - } - } + toolSessionDAO.removeToolSession(toolSession); } - + } } - } + } - /** - * 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 - */ - - private void parseGroupings(List groupingsList) - throws WDDXProcessorConversionException { - // iterate through the list of groupings objects - // each object should contain information groupingUUID, groupingID, - // groupingTypeID - if (groupingsList != null) { - Iterator iterator = groupingsList.iterator(); - while (iterator.hasNext()) { - Hashtable groupingDetails = (Hashtable) iterator.next(); - if (groupingDetails != null) { - Grouping grouping = extractGroupingObject(groupingDetails); - groupingDAO.insertOrUpdate(grouping); - groupings.put(grouping.getGroupingUIID(), grouping); - } - } - - } } + } - public Grouping extractGroupingObject(Hashtable groupingDetails) - throws WDDXProcessorConversionException { + /** + * 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 + */ - Integer groupingUUID = WDDXProcessor.convertToInteger(groupingDetails, - WDDXTAGS.GROUPING_UIID); - Integer groupingTypeID = WDDXProcessor.convertToInteger( - groupingDetails, WDDXTAGS.GROUPING_TYPE_ID); - if (groupingTypeID == null) { - throw new WDDXProcessorConversionException( - "groupingTypeID is missing"); + private void parseGroupings(List groupingsList) throws WDDXProcessorConversionException { + // iterate through the list of groupings objects + // each object should contain information groupingUUID, groupingID, + // groupingTypeID + if (groupingsList != null) { + Iterator iterator = groupingsList.iterator(); + while (iterator.hasNext()) { + Hashtable groupingDetails = (Hashtable) iterator.next(); + if (groupingDetails != null) { + Grouping grouping = extractGroupingObject(groupingDetails); + groupingDAO.insertOrUpdate(grouping); + groupings.put(grouping.getGroupingUIID(), grouping); } + } - Grouping grouping = groupings.get(groupingUUID); - // check that the grouping type is still okay - if it is we keep the - // grouping otherwise - // we get rid of the old hibernate object. - if (grouping != null) { - if (grouping.getGroupingTypeId().equals(groupingTypeID)) { - groupingsToDelete.remove(groupingUUID); - } - else { - groupings.remove(grouping.getGroupingUIID()); - grouping = null; - } - } + } + } - if (grouping == null) { - Object object = Grouping.getGroupingInstance(groupingTypeID); - grouping = (Grouping) object; + public Grouping extractGroupingObject(Hashtable groupingDetails) throws WDDXProcessorConversionException { - if (keyExists(groupingDetails, WDDXTAGS.GROUPING_UIID)) { - grouping.setGroupingUIID(WDDXProcessor.convertToInteger( - groupingDetails, WDDXTAGS.GROUPING_UIID)); - } - } + Integer groupingUUID = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.GROUPING_UIID); + Integer groupingTypeID = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.GROUPING_TYPE_ID); + if (groupingTypeID == null) { + throw new WDDXProcessorConversionException("groupingTypeID is missing"); + } - if (grouping.isRandomGrouping()) { - createRandomGrouping((RandomGrouping) grouping, groupingDetails); - } - else if (grouping.isChosenGrouping()) { - createChosenGrouping((ChosenGrouping) grouping, groupingDetails); - } + Grouping grouping = groupings.get(groupingUUID); + // check that the grouping type is still okay - if it is we keep the + // grouping otherwise + // we get rid of the old hibernate object. + if (grouping != null) { + if (grouping.getGroupingTypeId().equals(groupingTypeID)) { + groupingsToDelete.remove(groupingUUID); + } else { + groupings.remove(grouping.getGroupingUIID()); + grouping = null; + } + } - else if (grouping.isLearnerChoiceGrouping()) { - createLearnerChoiceGrouping((LearnerChoiceGrouping) grouping, - groupingDetails); - } - else { - createLessonClass((LessonClass) grouping, groupingDetails); - } + if (grouping == null) { + Object object = Grouping.getGroupingInstance(groupingTypeID); + grouping = (Grouping) object; - if (keyExists(groupingDetails, WDDXTAGS.MAX_NUMBER_OF_GROUPS)) { - grouping.setMaxNumberOfGroups(WDDXProcessor.convertToInteger( - groupingDetails, WDDXTAGS.MAX_NUMBER_OF_GROUPS)); - } + if (keyExists(groupingDetails, WDDXTAGS.GROUPING_UIID)) { + grouping.setGroupingUIID(WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.GROUPING_UIID)); + } + } - Set groupsToDelete = new HashSet(grouping.getGroups()); + if (grouping.isRandomGrouping()) { + createRandomGrouping((RandomGrouping) grouping, groupingDetails); + } else if (grouping.isChosenGrouping()) { + createChosenGrouping((ChosenGrouping) grouping, groupingDetails); + } - List groupsList = (Vector) groupingDetails.get(WDDXTAGS.GROUPS); - if (groupsList != null && groupsList.size() > 0) { - Iterator iter = groupsList.iterator(); - while (iter.hasNext()) { - Hashtable groupDetails = (Hashtable) iter.next(); - Group group = extractGroupObject(groupDetails, grouping); - groups.put(group.getGroupUIID(), group); - groupsToDelete.remove(group); - } - } + else if (grouping.isLearnerChoiceGrouping()) { + createLearnerChoiceGrouping((LearnerChoiceGrouping) grouping, groupingDetails); + } else { + createLessonClass((LessonClass) grouping, groupingDetails); + } - if (groupsToDelete.size() > 0) { - Iterator iter = groupsToDelete.iterator(); - while (iter.hasNext()) { - Group group = (Group) iter.next(); - if (group.getBranchActivities() != null) { - Iterator branchIter = group.getBranchActivities() - .iterator(); - while (branchIter.hasNext()) { - BranchActivityEntry entry = (BranchActivityEntry) branchIter - .next(); - entry.setGroup(null); - } - group.getBranchActivities().clear(); - } - grouping.getGroups().remove(group); - } - } - return grouping; + if (keyExists(groupingDetails, WDDXTAGS.MAX_NUMBER_OF_GROUPS)) { + grouping.setMaxNumberOfGroups(WDDXProcessor + .convertToInteger(groupingDetails, WDDXTAGS.MAX_NUMBER_OF_GROUPS)); } - @SuppressWarnings("unchecked") - private Group extractGroupObject(Hashtable groupDetails, Grouping grouping) - throws WDDXProcessorConversionException { + Set groupsToDelete = new HashSet(grouping.getGroups()); - Group group = null; - Integer groupUIID = WDDXProcessor.convertToInteger(groupDetails, - WDDXTAGS.GROUP_UIID); - if (groupUIID == null) { - throw new WDDXProcessorConversionException( - "Group is missing its UUID. Group " + groupDetails - + " grouping " + grouping); - } - Long groupID = WDDXProcessor.convertToLong(groupDetails, - WDDXTAGS.GROUP_ID); + List groupsList = (Vector) groupingDetails.get(WDDXTAGS.GROUPS); + if (groupsList != null && groupsList.size() > 0) { + Iterator iter = groupsList.iterator(); + while (iter.hasNext()) { + Hashtable groupDetails = (Hashtable) iter.next(); + Group group = extractGroupObject(groupDetails, grouping); + groups.put(group.getGroupUIID(), group); + groupsToDelete.remove(group); + } + } - // Does it exist already? If the group was created at runtime, there - // will be an ID but no IU ID field. - // If it was created in authoring, will have a UI ID and may or may not - // have an ID. - // So try to match up on UI ID first, failing that match on ID. Then the - // worst case, which is the group - // is created at runtime but then modified in authoring (and has has a - // new UI ID added) is handled. - if (grouping.getGroups() != null && grouping.getGroups().size() > 0) { - Group uiid_match = null; - Group id_match = null; - Iterator iter = grouping.getGroups().iterator(); - while (uiid_match == null && iter.hasNext()) { - Group possibleGroup = (Group) iter.next(); - if (groupUIID.equals(possibleGroup.getGroupUIID())) { - uiid_match = possibleGroup; - } - if (groupID != null - && groupID.equals(possibleGroup.getGroupId())) { - id_match = possibleGroup; - } - } - group = uiid_match != null ? uiid_match : id_match; + if (groupsToDelete.size() > 0) { + Iterator iter = groupsToDelete.iterator(); + while (iter.hasNext()) { + Group group = (Group) iter.next(); + if (group.getBranchActivities() != null) { + Iterator branchIter = group.getBranchActivities().iterator(); + while (branchIter.hasNext()) { + BranchActivityEntry entry = (BranchActivityEntry) branchIter.next(); + entry.setGroup(null); + } + group.getBranchActivities().clear(); } + grouping.getGroups().remove(group); + } + } + return grouping; + } - if (group == null) { - group = new Group(); - grouping.getGroups().add(group); - } + @SuppressWarnings("unchecked") + private Group extractGroupObject(Hashtable groupDetails, Grouping grouping) throws WDDXProcessorConversionException { - group.setGroupName(WDDXProcessor.convertToString(groupDetails, - WDDXTAGS.GROUP_NAME)); - group.setGrouping(grouping); - group.setGroupUIID(groupUIID); - - if (keyExists(groupDetails, WDDXTAGS.ORDER_ID)) { - group.setOrderId(WDDXProcessor.convertToInteger(groupDetails, - WDDXTAGS.ORDER_ID)); - } - else { - group.setOrderId(0); - } - - return group; + Group group = null; + Integer groupUIID = WDDXProcessor.convertToInteger(groupDetails, WDDXTAGS.GROUP_UIID); + if (groupUIID == null) { + throw new WDDXProcessorConversionException("Group is missing its UUID. Group " + groupDetails + + " grouping " + grouping); } + Long groupID = WDDXProcessor.convertToLong(groupDetails, WDDXTAGS.GROUP_ID); - private void createRandomGrouping(RandomGrouping randomGrouping, - Hashtable groupingDetails) throws WDDXProcessorConversionException { - // the two settings are mutually exclusive. Flash takes care of this, - // but we'll code it here too just to make sure. - Integer numLearnersPerGroup = WDDXProcessor.convertToInteger( - groupingDetails, WDDXTAGS.LEARNERS_PER_GROUP); - if (numLearnersPerGroup != null && numLearnersPerGroup.intValue() > 0) { - randomGrouping.setLearnersPerGroup(numLearnersPerGroup); - randomGrouping.setNumberOfGroups(null); + // Does it exist already? If the group was created at runtime, there + // will be an ID but no IU ID field. + // If it was created in authoring, will have a UI ID and may or may not + // have an ID. + // So try to match up on UI ID first, failing that match on ID. Then the + // worst case, which is the group + // is created at runtime but then modified in authoring (and has has a + // new UI ID added) is handled. + if (grouping.getGroups() != null && grouping.getGroups().size() > 0) { + Group uiid_match = null; + Group id_match = null; + Iterator iter = grouping.getGroups().iterator(); + while (uiid_match == null && iter.hasNext()) { + Group possibleGroup = (Group) iter.next(); + if (groupUIID.equals(possibleGroup.getGroupUIID())) { + uiid_match = possibleGroup; } - else { - Integer numGroups = WDDXProcessor.convertToInteger(groupingDetails, - WDDXTAGS.NUMBER_OF_GROUPS); - if (numGroups != null && numGroups.intValue() > 0) { - randomGrouping.setNumberOfGroups(numGroups); - } - else { - randomGrouping.setNumberOfGroups(null); - } - randomGrouping.setLearnersPerGroup(null); + if (groupID != null && groupID.equals(possibleGroup.getGroupId())) { + id_match = possibleGroup; } + } + group = uiid_match != null ? uiid_match : id_match; } - private void createChosenGrouping(ChosenGrouping chosenGrouping, - Hashtable groupingDetails) throws WDDXProcessorConversionException { - // no extra properties as yet + if (group == null) { + group = new Group(); + grouping.getGroups().add(group); } - /** - * 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. - * @throws WDDXProcessorConversionException - * @throws ObjectExtractorException - */ - @SuppressWarnings("unchecked") - private void parseActivities(List activitiesList) - throws WDDXProcessorConversionException, ObjectExtractorException { + group.setGroupName(WDDXProcessor.convertToString(groupDetails, WDDXTAGS.GROUP_NAME)); + group.setGrouping(grouping); + group.setGroupUIID(groupUIID); - if (activitiesList != null) { - Iterator iterator = activitiesList.iterator(); - while (iterator.hasNext()) { - Hashtable activityDetails = (Hashtable) iterator.next(); - Activity activity = extractActivityObject(activityDetails); - activityDAO.insertOrUpdate(activity); - newActivityMap.put(activity.getActivityUIID(), activity); - } - } + if (keyExists(groupDetails, WDDXTAGS.ORDER_ID)) { + group.setOrderId(WDDXProcessor.convertToInteger(groupDetails, WDDXTAGS.ORDER_ID)); + } else { + group.setOrderId(0); + } - // clear the transitions. - // clear the old set and reset up the activities set. Done this way to - // keep the Hibernate cascading happy. - // this means we don't have to manually remove the transition object. - // Note: This will leave orphan content in the tool tables. It can be - // removed by the tool content cleaning job, - // which may be run from the admin screen or via a cron job. + return group; + } - learningDesign.getActivities().clear(); - learningDesign.getActivities().addAll(newActivityMap.values()); - - // TODO: Need to double check that the toolID/toolContentID combinations - // match entries in lams_tool_content table, or put FK on table. - learningDesignDAO.insertOrUpdate(learningDesign); + private void createRandomGrouping(RandomGrouping randomGrouping, Hashtable groupingDetails) + throws WDDXProcessorConversionException { + // the two settings are mutually exclusive. Flash takes care of this, + // but we'll code it here too just to make sure. + Integer numLearnersPerGroup = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.LEARNERS_PER_GROUP); + if (numLearnersPerGroup != null && numLearnersPerGroup.intValue() > 0) { + randomGrouping.setLearnersPerGroup(numLearnersPerGroup); + randomGrouping.setNumberOfGroups(null); + } else { + Integer numGroups = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.NUMBER_OF_GROUPS); + if (numGroups != null && numGroups.intValue() > 0) { + randomGrouping.setNumberOfGroups(numGroups); + } else { + randomGrouping.setNumberOfGroups(null); + } + randomGrouping.setLearnersPerGroup(null); } + } - /** - * 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. - * @throws WDDXProcessorConversionException - * @throws ObjectExtractorException - */ - @SuppressWarnings("unchecked") - private void parseCompetenceMappings(List activitiesList) - throws WDDXProcessorConversionException, ObjectExtractorException { + private void createChosenGrouping(ChosenGrouping chosenGrouping, Hashtable groupingDetails) + throws WDDXProcessorConversionException { + // no extra properties as yet + } - if (activitiesList != null) { - Iterator iterator = activitiesList.iterator(); - while (iterator.hasNext()) { - Hashtable activityDetails = (Hashtable) iterator.next(); + /** + * 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. + * @throws WDDXProcessorConversionException + * @throws ObjectExtractorException + */ + @SuppressWarnings("unchecked") + private void parseActivities(List activitiesList) throws WDDXProcessorConversionException, ObjectExtractorException { - // Check that this is a tool activity, otherwise continue to the - // next iteration - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)) { - int actType = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID); - if (actType != Activity.TOOL_ACTIVITY_TYPE) { - continue; - } - } + if (activitiesList != null) { + Iterator iterator = activitiesList.iterator(); + while (iterator.hasNext()) { + Hashtable activityDetails = (Hashtable) iterator.next(); + Activity activity = extractActivityObject(activityDetails); + activityDAO.insertOrUpdate(activity); + newActivityMap.put(activity.getActivityUIID(), activity); + } + } - // Get the tool activity using the UIID and the learningDesignID - ToolActivity toolActivity = null; - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_UIID)) { - toolActivity = (ToolActivity) activityDAO - .getActivityByUIID(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_UIID), - learningDesign); - } - else { - continue; - } + // clear the transitions. + // clear the old set and reset up the activities set. Done this way to + // keep the Hibernate cascading happy. + // this means we don't have to manually remove the transition object. + // Note: This will leave orphan content in the tool tables. It can be + // removed by the tool content cleaning job, + // which may be run from the admin screen or via a cron job. - if (keyExists(activityDetails, WDDXTAGS.COMPETENCE_MAPPINGS)) { - List competenceMappingsList = (Vector) activityDetails - .get(WDDXTAGS.COMPETENCE_MAPPINGS); + learningDesign.getActivities().clear(); + learningDesign.getActivities().addAll(newActivityMap.values()); - for (String competenceMappingEntry : competenceMappingsList) { + // TODO: Need to double check that the toolID/toolContentID combinations + // match entries in lams_tool_content table, or put FK on table. + learningDesignDAO.insertOrUpdate(learningDesign); + } - if (toolActivity.getActivityId() != null) { + /** + * 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. + * @throws WDDXProcessorConversionException + * @throws ObjectExtractorException + */ + @SuppressWarnings("unchecked") + private void parseCompetenceMappings(List activitiesList) throws WDDXProcessorConversionException, + ObjectExtractorException { - // First get the competence from the competence - // mapping entry in the hashtable - Competence competence = competenceDAO - .getCompetence(toolActivity - .getLearningDesign(), - competenceMappingEntry); - if (competence == null) { - continue; - } + if (activitiesList != null) { + Iterator iterator = activitiesList.iterator(); + while (iterator.hasNext()) { + Hashtable activityDetails = (Hashtable) iterator.next(); - // Now get the competence mapping using the tool - // activity and the competence as reference - CompetenceMapping competenceMapping = competenceMappingDAO - .getCompetenceMapping(toolActivity, - competence); + // Check that this is a tool activity, otherwise continue to the + // next iteration + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)) { + int actType = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID); + if (actType != Activity.TOOL_ACTIVITY_TYPE) { + continue; + } + } - // Only save new competence mappings, no need to - // update existing - if (competenceMapping == null) { - CompetenceMapping newMapping = new CompetenceMapping(); - newMapping.setCompetence(competence); - newMapping.setToolActivity(toolActivity); + // Get the tool activity using the UIID and the learningDesignID + ToolActivity toolActivity = null; + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_UIID)) { + toolActivity = (ToolActivity) activityDAO.getActivityByUIID(WDDXProcessor.convertToInteger( + activityDetails, WDDXTAGS.ACTIVITY_UIID), learningDesign); + } else { + continue; + } - // newMappings.add(newMapping); - competenceMappingDAO.saveOrUpdate(newMapping); - // toolActivity.getCompetenceMappings().add(newMapping); - } - } - else { - Competence competence = competenceDAO - .getCompetence(learningDesign, - competenceMappingEntry); - CompetenceMapping newMapping = new CompetenceMapping(); - newMapping.setCompetence(competence); - newMapping.setToolActivity(toolActivity); - competenceMappingDAO.saveOrUpdate(newMapping); - // toolActivity.getCompetenceMappings().add(newMapping); - } - } + if (keyExists(activityDetails, WDDXTAGS.COMPETENCE_MAPPINGS)) { + List competenceMappingsList = (Vector) activityDetails.get(WDDXTAGS.COMPETENCE_MAPPINGS); - // delete any pre-existing mappings that have been deleted - Set existingMappings = toolActivity - .getCompetenceMappings(); - if (existingMappings != null) { - Set removeCompetenceMappings = new HashSet(); - if (competenceMappingsList != null - && competenceMappingsList.size() > 0) { - for (CompetenceMapping competenceMapping : existingMappings) { - boolean remove = true; + for (String competenceMappingEntry : competenceMappingsList) { - for (String competenceMappingEntry : competenceMappingsList) { - if (competenceMappingEntry - .equals(competenceMapping - .getCompetence().getTitle())) { - remove = false; - break; - } - } + if (toolActivity.getActivityId() != null) { - if (remove) { - removeCompetenceMappings - .add(competenceMapping); - } - } - } - else { - removeCompetenceMappings.addAll(existingMappings); - } - competenceMappingDAO - .deleteAll(removeCompetenceMappings); - toolActivity.getCompetenceMappings().removeAll( - removeCompetenceMappings); - } - } - } - } - } + // First get the competence from the competence + // mapping entry in the hashtable + Competence competence = competenceDAO.getCompetence(toolActivity.getLearningDesign(), + competenceMappingEntry); + if (competence == null) { + continue; + } - /** - * 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. - * @throws WDDXProcessorConversionException - * @throws ObjectExtractorException - */ - @SuppressWarnings("unchecked") - private void parseCompetences(List competenceList, - LearningDesign learningDesign) - throws WDDXProcessorConversionException, ObjectExtractorException { + // Now get the competence mapping using the tool + // activity and the competence as reference + CompetenceMapping competenceMapping = competenceMappingDAO.getCompetenceMapping( + toolActivity, competence); - Set existingCompetences = learningDesign.getCompetences(); - if (competenceList != null) { - for (Hashtable competenceTable : competenceList) { - String title = (String) competenceTable.get("title"); - String description = (String) competenceTable - .get("description"); + // Only save new competence mappings, no need to + // update existing + if (competenceMapping == null) { + CompetenceMapping newMapping = new CompetenceMapping(); + newMapping.setCompetence(competence); + newMapping.setToolActivity(toolActivity); - if (getComptenceFromSet(existingCompetences, title) != null) { - Competence updateCompetence = getComptenceFromSet( - existingCompetences, title); - updateCompetence.setDescription(description); - competenceDAO.saveOrUpdate(updateCompetence); - } - else { - Competence newCompetence = new Competence(); - newCompetence.setTitle(title); - newCompetence.setDescription(description); - newCompetence.setLearningDesign(learningDesign); - competenceDAO.saveOrUpdate(newCompetence); - } + // newMappings.add(newMapping); + competenceMappingDAO.saveOrUpdate(newMapping); + // toolActivity.getCompetenceMappings().add(newMapping); + } + } else { + Competence competence = competenceDAO.getCompetence(learningDesign, competenceMappingEntry); + CompetenceMapping newMapping = new CompetenceMapping(); + newMapping.setCompetence(competence); + newMapping.setToolActivity(toolActivity); + competenceMappingDAO.saveOrUpdate(newMapping); + // toolActivity.getCompetenceMappings().add(newMapping); } + } - // now go through and delete any competences from the old list, - // that dont exist in the new list. - Set removeCompetences = new HashSet(); - if (existingCompetences != null) { - if (competenceList != null && competenceList.size() > 0) { - for (Competence existingCompetence : existingCompetences) { - boolean remove = true; - for (Hashtable competenceTable : competenceList) { - if (existingCompetence.getTitle().equals( - competenceTable.get("title"))) { - remove = false; - break; - } - } + // delete any pre-existing mappings that have been deleted + Set existingMappings = toolActivity.getCompetenceMappings(); + if (existingMappings != null) { + Set removeCompetenceMappings = new HashSet(); + if (competenceMappingsList != null && competenceMappingsList.size() > 0) { + for (CompetenceMapping competenceMapping : existingMappings) { + boolean remove = true; - if (remove) { - removeCompetences.add(existingCompetence); - } - } + for (String competenceMappingEntry : competenceMappingsList) { + if (competenceMappingEntry.equals(competenceMapping.getCompetence().getTitle())) { + remove = false; + break; + } } - else { - removeCompetences.addAll(existingCompetences); - } - // competenceDAO.deleteAll(removeCompetences); - learningDesign.getCompetences().removeAll(removeCompetences); - } - } - } - private Competence getComptenceFromSet(Set competences, - String title) { - if (competences != null) { - for (Competence competence : competences) { - if (competence.getTitle().equals(title)) { - return competence; + if (remove) { + removeCompetenceMappings.add(competenceMapping); } + } + } else { + removeCompetenceMappings.addAll(existingMappings); } - + competenceMappingDAO.deleteAll(removeCompetenceMappings); + toolActivity.getCompetenceMappings().removeAll(removeCompetenceMappings); + } } - return null; + } } + } - /** - * 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 - * @throws WDDXProcessorConversionException - * @throws ObjectExtractorException - */ - private void parseActivitiesToMatchUpParentandInputActivities( - List activitiesList) throws WDDXProcessorConversionException, - ObjectExtractorException { - if (activitiesList != null) { - Iterator iterator = activitiesList.iterator(); - while (iterator.hasNext()) { + /** + * 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. + * @throws WDDXProcessorConversionException + * @throws ObjectExtractorException + */ + @SuppressWarnings("unchecked") + private void parseCompetences(List competenceList, LearningDesign learningDesign) + throws WDDXProcessorConversionException, ObjectExtractorException { - Hashtable activityDetails = (Hashtable) iterator.next(); + Set existingCompetences = learningDesign.getCompetences(); + if (competenceList != null) { + for (Hashtable competenceTable : competenceList) { + String title = (String) competenceTable.get("title"); + String description = (String) competenceTable.get("description"); - Integer activityUUID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_UIID); - Activity existingActivity = newActivityMap.get(activityUUID); - - // match up activity to parent based on UIID - if (keyExists(activityDetails, WDDXTAGS.PARENT_UIID)) { - Integer parentUIID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.PARENT_UIID); - if (parentUIID != null) { - Activity parentActivity = newActivityMap - .get(parentUIID); - if (parentActivity == null) { - throw new ObjectExtractorException( - "Parent activity " - + parentUIID - + " missing for activity " - + existingActivity.getTitle() - + ": " - + existingActivity - .getActivityUIID()); - } - existingActivity.setParentActivity(parentActivity); - existingActivity.setParentUIID(parentUIID); - if (parentActivity.isComplexActivity()) { - ((ComplexActivity) parentActivity) - .addActivity(existingActivity); - activityDAO.update(parentActivity); - } - - } - else { - existingActivity.setParentActivity(null); - existingActivity.setParentUIID(null); - existingActivity.setOrderId(null); // top level - // activities don't - // have order ids. - } - } - - // match up activity to input activities based on UIID. At - // present there will be only one input activity - existingActivity.getInputActivities().clear(); - Integer inputActivityUIID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.INPUT_TOOL_ACTIVITY_UIID); - if (inputActivityUIID != null) { - Activity inputActivity = newActivityMap - .get(inputActivityUIID); - if (inputActivity == null) { - throw new ObjectExtractorException("Input activity " - + inputActivityUIID + " missing for activity " - + existingActivity.getTitle() + ": " - + existingActivity.getActivityUIID()); - } - existingActivity.getInputActivities().add(inputActivity); - } - - activityDAO.update(existingActivity); - - } + if (getComptenceFromSet(existingCompetences, title) != null) { + Competence updateCompetence = getComptenceFromSet(existingCompetences, title); + updateCompetence.setDescription(description); + competenceDAO.saveOrUpdate(updateCompetence); + } else { + Competence newCompetence = new Competence(); + newCompetence.setTitle(title); + newCompetence.setDescription(description); + newCompetence.setLearningDesign(learningDesign); + competenceDAO.saveOrUpdate(newCompetence); } - } + } - /** - * 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 - * @param learningDesign - * @throws WDDXProcessorConversionException - */ - @SuppressWarnings("unchecked") - private void parseTransitions(List transitionsList) - throws WDDXProcessorConversionException { - - HashMap newMap = new HashMap(); - - if (transitionsList != null) { - Iterator iterator = transitionsList.iterator(); - while (iterator.hasNext()) { - Hashtable transitionDetails = (Hashtable) iterator.next(); - Transition transition = extractTransitionObject(transitionDetails); - // Check if transition actually exists. extractTransitionObject - // returns null - // if neither the to/from activity exists. - if (transition != null) { - transitionDAO.insertOrUpdate(transition); - newMap.put(transition.getTransitionUIID(), transition); - } + // now go through and delete any competences from the old list, + // that dont exist in the new list. + Set removeCompetences = new HashSet(); + if (existingCompetences != null) { + if (competenceList != null && competenceList.size() > 0) { + for (Competence existingCompetence : existingCompetences) { + boolean remove = true; + for (Hashtable competenceTable : competenceList) { + if (existingCompetence.getTitle().equals(competenceTable.get("title"))) { + remove = false; + break; + } } - } - // clean up the links for any old transitions. - Iterator iter = learningDesign.getTransitions().iterator(); - while (iter.hasNext()) { - Transition element = (Transition) iter.next(); - Integer uiID = element.getTransitionUIID(); - Transition match = newMap.get(uiID); - if (match == null) { - // transition is no more, clean up the old activity links - cleanupTransition(element); + if (remove) { + removeCompetences.add(existingCompetence); } + } + } else { + removeCompetences.addAll(existingCompetences); } - // clear the old set and reset up the transition set. Done this way to - // keep the Hibernate cascading happy. - // this means we don't have to manually remove the transition object. - // Note: This will leave orphan content in the tool tables. It can be - // removed by the tool content cleaning job, - // which may be run from the admin screen or via a cron job. - learningDesign.getTransitions().clear(); - learningDesign.getTransitions().addAll(newMap.values()); - - learningDesignDAO.insertOrUpdate(learningDesign); - + // competenceDAO.deleteAll(removeCompetences); + learningDesign.getCompetences().removeAll(removeCompetences); + } } + } - public Activity extractActivityObject(Hashtable activityDetails) - throws WDDXProcessorConversionException, ObjectExtractorException { - - // it is assumed that the activityUUID will always be sent by flash. - Integer activityUUID = WDDXProcessor.convertToInteger(activityDetails, - WDDXTAGS.ACTIVITY_UIID); - Activity activity = null; - Integer activityTypeID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID); - if (activityTypeID == null) { - throw new ObjectExtractorException("activityTypeID missing"); + private Competence getComptenceFromSet(Set competences, String title) { + if (competences != null) { + for (Competence competence : competences) { + if (competence.getTitle().equals(title)) { + return competence; } + } - // get the activity with the particular activity uuid, if null, then new - // object needs to be created. - Activity existingActivity = activityDAO.getActivityByUIID(activityUUID, - learningDesign); - if (existingActivity != null - && !existingActivity.getActivityTypeId().equals(activityTypeID)) { - existingActivity = null; - } + } + return null; + } - if (existingActivity != null) { - activity = existingActivity; - } - else { - activity = Activity.getActivityInstance(activityTypeID.intValue()); - } - processActivityType(activity, activityDetails); + /** + * 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 + * @throws WDDXProcessorConversionException + * @throws ObjectExtractorException + */ + private void parseActivitiesToMatchUpParentandInputActivities(List activitiesList) + throws WDDXProcessorConversionException, ObjectExtractorException { + if (activitiesList != null) { + Iterator iterator = activitiesList.iterator(); + while (iterator.hasNext()) { - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)) { - activity.setActivityTypeId(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)); - } - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_UIID)) { - activity.setActivityUIID(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_UIID)); - } - if (keyExists(activityDetails, WDDXTAGS.DESCRIPTION)) { - activity.setDescription(WDDXProcessor.convertToString( - activityDetails, WDDXTAGS.DESCRIPTION)); - } - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TITLE)) { - activity.setTitle(WDDXProcessor.convertToString(activityDetails, - WDDXTAGS.ACTIVITY_TITLE)); - } - if (keyExists(activityDetails, WDDXTAGS.HELP_TEXT)) { - activity.setHelpText(WDDXProcessor.convertToString(activityDetails, - WDDXTAGS.HELP_TEXT)); - } + Hashtable activityDetails = (Hashtable) iterator.next(); - activity.setXcoord(getCoord(activityDetails, WDDXTAGS.XCOORD)); - activity.setYcoord(getCoord(activityDetails, WDDXTAGS.YCOORD)); + Integer activityUUID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_UIID); + Activity existingActivity = newActivityMap.get(activityUUID); - if (keyExists(activityDetails, WDDXTAGS.GROUPING_UIID)) { - Integer groupingUIID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.GROUPING_UIID); - if (groupingUIID != null) { - Grouping grouping = groupings.get(groupingUIID); - if (grouping != null) { - setGrouping(activity, grouping, groupingUIID); - } - else { - log - .warn("Unable to find matching grouping for groupingUIID" - + groupingUIID - + ". Activity UUID" - + activityUUID + " will not be grouped."); - clearGrouping(activity); - } + // match up activity to parent based on UIID + if (keyExists(activityDetails, WDDXTAGS.PARENT_UIID)) { + Integer parentUIID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.PARENT_UIID); + if (parentUIID != null) { + Activity parentActivity = newActivityMap.get(parentUIID); + if (parentActivity == null) { + throw new ObjectExtractorException("Parent activity " + parentUIID + + " missing for activity " + existingActivity.getTitle() + ": " + + existingActivity.getActivityUIID()); } - else { - clearGrouping(activity); + existingActivity.setParentActivity(parentActivity); + existingActivity.setParentUIID(parentUIID); + if (parentActivity.isComplexActivity()) { + ((ComplexActivity) parentActivity).addActivity(existingActivity); + activityDAO.update(parentActivity); } + + } else { + existingActivity.setParentActivity(null); + existingActivity.setParentUIID(null); + existingActivity.setOrderId(null); // top level + // activities don't + // have order ids. + } } - else { - clearGrouping(activity); - } - if (keyExists(activityDetails, WDDXTAGS.ORDER_ID)) { - activity.setOrderId(WDDXProcessor.convertToInteger(activityDetails, - WDDXTAGS.ORDER_ID)); + // match up activity to input activities based on UIID. At + // present there will be only one input activity + existingActivity.getInputActivities().clear(); + Integer inputActivityUIID = WDDXProcessor.convertToInteger(activityDetails, + WDDXTAGS.INPUT_TOOL_ACTIVITY_UIID); + if (inputActivityUIID != null) { + Activity inputActivity = newActivityMap.get(inputActivityUIID); + if (inputActivity == null) { + throw new ObjectExtractorException("Input activity " + inputActivityUIID + + " missing for activity " + existingActivity.getTitle() + ": " + + existingActivity.getActivityUIID()); + } + existingActivity.getInputActivities().add(inputActivity); } - if (keyExists(activityDetails, WDDXTAGS.DEFINE_LATER)) { - activity.setDefineLater(WDDXProcessor.convertToBoolean( - activityDetails, WDDXTAGS.DEFINE_LATER)); - } - activity.setLearningDesign(learningDesign); + activityDAO.update(existingActivity); - if (keyExists(activityDetails, WDDXTAGS.LEARNING_LIBRARY_ID)) { - Long learningLibraryID = WDDXProcessor.convertToLong( - activityDetails, WDDXTAGS.LEARNING_LIBRARY_ID); - if (learningLibraryID != null) { - LearningLibrary library = learningLibraryDAO - .getLearningLibraryById(learningLibraryID); - activity.setLearningLibrary(library); - } - else { - activity.setLearningLibrary(null); - } - } + } + } + } - // Set creation date based on the server timezone, not the client. - if (activity.getCreateDateTime() == null) { - activity.setCreateDateTime(modificationDate); - } + /** + * 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 + * @param learningDesign + * @throws WDDXProcessorConversionException + */ + @SuppressWarnings("unchecked") + private void parseTransitions(List transitionsList) throws WDDXProcessorConversionException { - if (keyExists(activityDetails, WDDXTAGS.RUN_OFFLINE)) { - activity.setRunOffline(WDDXProcessor.convertToBoolean( - activityDetails, WDDXTAGS.RUN_OFFLINE)); - } - if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_CATEGORY_ID)) { - activity.setActivityCategoryID(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.ACTIVITY_CATEGORY_ID)); - } - if (keyExists(activityDetails, WDDXTAGS.LIBRARY_IMAGE)) { - activity.setLibraryActivityUiImage(WDDXProcessor.convertToString( - activityDetails, WDDXTAGS.LIBRARY_IMAGE)); - } + HashMap newMap = new HashMap(); - if (keyExists(activityDetails, WDDXTAGS.GROUPING_SUPPORT_TYPE)) { - activity.setGroupingSupportType(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.GROUPING_SUPPORT_TYPE)); + if (transitionsList != null) { + Iterator iterator = transitionsList.iterator(); + while (iterator.hasNext()) { + Hashtable transitionDetails = (Hashtable) iterator.next(); + Transition transition = extractTransitionObject(transitionDetails); + // Check if transition actually exists. extractTransitionObject + // returns null + // if neither the to/from activity exists. + if (transition != null) { + transitionDAO.insertOrUpdate(transition); + newMap.put(transition.getTransitionUIID(), transition); } + } + } - if (keyExists(activityDetails, WDDXTAGS.STOP_AFTER_ACTIVITY)) { - activity.setStopAfterActivity(WDDXProcessor.convertToBoolean( - activityDetails, WDDXTAGS.STOP_AFTER_ACTIVITY)); - } - - return activity; + // clean up the links for any old transitions. + Iterator iter = learningDesign.getTransitions().iterator(); + while (iter.hasNext()) { + Transition element = (Transition) iter.next(); + Integer uiID = element.getTransitionUIID(); + Transition match = newMap.get(uiID); + if (match == null) { + // transition is no more, clean up the old activity links + cleanupTransition(element); + } } + // clear the old set and reset up the transition set. Done this way to + // keep the Hibernate cascading happy. + // this means we don't have to manually remove the transition object. + // Note: This will leave orphan content in the tool tables. It can be + // removed by the tool content cleaning job, + // which may be run from the admin screen or via a cron job. + learningDesign.getTransitions().clear(); + learningDesign.getTransitions().addAll(newMap.values()); - private Integer getCoord(Hashtable details, String wddxtag) - throws WDDXProcessorConversionException { - Integer coord = null; - if (keyExists(details, wddxtag)) { - coord = WDDXProcessor.convertToInteger(details, wddxtag); - } - return coord == null || coord >= 0 ? coord - : ObjectExtractor.DEFAULT_COORD; + learningDesignDAO.insertOrUpdate(learningDesign); + + } + + public Activity extractActivityObject(Hashtable activityDetails) throws WDDXProcessorConversionException, + ObjectExtractorException { + + // it is assumed that the activityUUID will always be sent by flash. + Integer activityUUID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_UIID); + Activity activity = null; + Integer activityTypeID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID); + if (activityTypeID == null) { + throw new ObjectExtractorException("activityTypeID missing"); } - private void clearGrouping(Activity activity) { - activity.setGrouping(null); - activity.setGroupingUIID(null); - activity.setApplyGrouping(false); + // get the activity with the particular activity uuid, if null, then new + // object needs to be created. + Activity existingActivity = activityDAO.getActivityByUIID(activityUUID, learningDesign); + if (existingActivity != null && !existingActivity.getActivityTypeId().equals(activityTypeID)) { + existingActivity = null; } - private void setGrouping(Activity activity, Grouping grouping, - Integer groupingUIID) { - activity.setGrouping(grouping); - activity.setGroupingUIID(groupingUIID); - activity.setApplyGrouping(true); + if (existingActivity != null) { + activity = existingActivity; + } else { + activity = Activity.getActivityInstance(activityTypeID.intValue()); } + processActivityType(activity, activityDetails); - private void processActivityType(Activity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException, - ObjectExtractorException { - if (activity.isGroupingActivity()) { - buildGroupingActivity((GroupingActivity) activity, activityDetails); - } - else if (activity.isToolActivity()) { - buildToolActivity((ToolActivity) activity, activityDetails); - } - else if (activity.isGateActivity()) { - buildGateActivity(activity, activityDetails); - } - else { - buildComplexActivity((ComplexActivity) activity, activityDetails); - } + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)) { + activity.setActivityTypeId(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_TYPE_ID)); } + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_UIID)) { + activity.setActivityUIID(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ACTIVITY_UIID)); + } + if (keyExists(activityDetails, WDDXTAGS.DESCRIPTION)) { + activity.setDescription(WDDXProcessor.convertToString(activityDetails, WDDXTAGS.DESCRIPTION)); + } + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_TITLE)) { + activity.setTitle(WDDXProcessor.convertToString(activityDetails, WDDXTAGS.ACTIVITY_TITLE)); + } + if (keyExists(activityDetails, WDDXTAGS.HELP_TEXT)) { + activity.setHelpText(WDDXProcessor.convertToString(activityDetails, WDDXTAGS.HELP_TEXT)); + } - private void buildComplexActivity(ComplexActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException, - ObjectExtractorException { - // clear all the children - will be built up again by - // parseActivitiesToMatchUpParentActivityByParentUIID - // we don't use all-delete-orphan on the activities relationship so we - // can do this clear. - activity.getActivities().clear(); + activity.setXcoord(getCoord(activityDetails, WDDXTAGS.XCOORD)); + activity.setYcoord(getCoord(activityDetails, WDDXTAGS.YCOORD)); - activity.setDefaultActivity(null); - Integer defaultActivityMapUIID = WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.DEFAULT_ACTIVITY_UIID); - if (defaultActivityMapUIID != null) { - defaultActivityMap.put(defaultActivityMapUIID, activity); + if (keyExists(activityDetails, WDDXTAGS.GROUPING_UIID)) { + Integer groupingUIID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.GROUPING_UIID); + if (groupingUIID != null) { + Grouping grouping = groupings.get(groupingUIID); + if (grouping != null) { + setGrouping(activity, grouping, groupingUIID); + } else { + log.warn("Unable to find matching grouping for groupingUIID" + groupingUIID + ". Activity UUID" + + activityUUID + " will not be grouped."); + clearGrouping(activity); } + } else { + clearGrouping(activity); + } + } else { + clearGrouping(activity); + } - if (activity instanceof OptionsActivity) { - buildOptionsActivity((OptionsActivity) activity, activityDetails); - } - else if (activity instanceof ParallelActivity) { - buildParallelActivity((ParallelActivity) activity, activityDetails); - } - else if (activity instanceof BranchingActivity) { - buildBranchingActivity((BranchingActivity) activity, - activityDetails); - } - else { - buildSequenceActivity((SequenceActivity) activity, activityDetails); - } + if (keyExists(activityDetails, WDDXTAGS.ORDER_ID)) { + activity.setOrderId(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.ORDER_ID)); } + if (keyExists(activityDetails, WDDXTAGS.DEFINE_LATER)) { + activity.setDefineLater(WDDXProcessor.convertToBoolean(activityDetails, WDDXTAGS.DEFINE_LATER)); + } - private void buildBranchingActivity(BranchingActivity branchingActivity, - Hashtable activityDetails) throws WDDXProcessorConversionException, - ObjectExtractorException { - if (branchingActivity.isChosenBranchingActivity()) { - branchingActivity - .setSystemTool(getSystemTool(SystemTool.TEACHER_CHOSEN_BRANCHING)); - } - else if (branchingActivity.isGroupBranchingActivity()) { - branchingActivity - .setSystemTool(getSystemTool(SystemTool.GROUP_BASED_BRANCHING)); - } - else if (branchingActivity.isToolBranchingActivity()) { - branchingActivity - .setSystemTool(getSystemTool(SystemTool.TOOL_BASED_BRANCHING)); - } + activity.setLearningDesign(learningDesign); - branchingActivity.setStartXcoord(getCoord(activityDetails, - WDDXTAGS.START_XCOORD)); - branchingActivity.setStartYcoord(getCoord(activityDetails, - WDDXTAGS.START_YCOORD)); - branchingActivity.setEndXcoord(getCoord(activityDetails, - WDDXTAGS.END_XCOORD)); - branchingActivity.setEndYcoord(getCoord(activityDetails, - WDDXTAGS.END_YCOORD)); + if (keyExists(activityDetails, WDDXTAGS.LEARNING_LIBRARY_ID)) { + Long learningLibraryID = WDDXProcessor.convertToLong(activityDetails, WDDXTAGS.LEARNING_LIBRARY_ID); + if (learningLibraryID != null) { + LearningLibrary library = learningLibraryDAO.getLearningLibraryById(learningLibraryID); + activity.setLearningLibrary(library); + } else { + activity.setLearningLibrary(null); + } } - private void buildGroupingActivity(GroupingActivity groupingActivity, - Hashtable activityDetails) throws WDDXProcessorConversionException, - ObjectExtractorException { - /** - * 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); - if (grouping != null) { - groupingActivity.setCreateGrouping(grouping); - groupingActivity.setCreateGroupingUIID(createGroupingUIID); - } - - SystemTool systemTool = getSystemTool(SystemTool.GROUPING); - groupingActivity.setSystemTool(systemTool); - - /* - * Hashtable groupingDetails = (Hashtable) - * activityDetails.get(WDDXTAGS.GROUPING_DTO); if( groupingDetails != - * null ){ Grouping grouping = extractGroupingObject(groupingDetails); - * groupingActivity.setCreateGrouping(grouping); - * groupingActivity.setCreateGroupingUIID(grouping.getGroupingUIID()); } - * else { groupingActivity.setCreateGrouping(null); - * groupingActivity.setCreateGroupingUIID(null); } - */ + // Set creation date based on the server timezone, not the client. + if (activity.getCreateDateTime() == null) { + activity.setCreateDateTime(modificationDate); } - private void buildOptionsActivity(OptionsActivity optionsActivity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - if (keyExists(activityDetails, WDDXTAGS.MAX_OPTIONS)) { - optionsActivity.setMaxNumberOfOptions(WDDXProcessor - .convertToInteger(activityDetails, WDDXTAGS.MAX_OPTIONS)); - } - if (keyExists(activityDetails, WDDXTAGS.MIN_OPTIONS)) { - optionsActivity.setMinNumberOfOptions(WDDXProcessor - .convertToInteger(activityDetails, WDDXTAGS.MIN_OPTIONS)); - } - if (keyExists(activityDetails, WDDXTAGS.OPTIONS_INSTRUCTIONS)) { - optionsActivity.setOptionsInstructions(WDDXProcessor - .convertToString(activityDetails, - WDDXTAGS.OPTIONS_INSTRUCTIONS)); - } + if (keyExists(activityDetails, WDDXTAGS.RUN_OFFLINE)) { + activity.setRunOffline(WDDXProcessor.convertToBoolean(activityDetails, WDDXTAGS.RUN_OFFLINE)); } + if (keyExists(activityDetails, WDDXTAGS.ACTIVITY_CATEGORY_ID)) { + activity.setActivityCategoryID(WDDXProcessor.convertToInteger(activityDetails, + WDDXTAGS.ACTIVITY_CATEGORY_ID)); + } + if (keyExists(activityDetails, WDDXTAGS.LIBRARY_IMAGE)) { + activity.setLibraryActivityUiImage(WDDXProcessor.convertToString(activityDetails, WDDXTAGS.LIBRARY_IMAGE)); + } - private void buildParallelActivity(ParallelActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { + if (keyExists(activityDetails, WDDXTAGS.GROUPING_SUPPORT_TYPE)) { + activity.setGroupingSupportType(WDDXProcessor.convertToInteger(activityDetails, + WDDXTAGS.GROUPING_SUPPORT_TYPE)); } - private void buildSequenceActivity(SequenceActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - activity.setSystemTool(getSystemTool(SystemTool.SEQUENCE)); + if (keyExists(activityDetails, WDDXTAGS.STOP_AFTER_ACTIVITY)) { + activity + .setStopAfterActivity(WDDXProcessor.convertToBoolean(activityDetails, WDDXTAGS.STOP_AFTER_ACTIVITY)); } - private void buildToolActivity(ToolActivity toolActivity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - if (log.isDebugEnabled()) { - log.debug("In tool activity UUID" - + activityDetails.get(WDDXTAGS.ACTIVITY_UIID) - + " tool content id=" - + activityDetails.get(WDDXTAGS.TOOL_CONTENT_ID)); - } - if (keyExists(activityDetails, WDDXTAGS.TOOL_CONTENT_ID)) { - toolActivity.setToolContentId(WDDXProcessor.convertToLong( - activityDetails, WDDXTAGS.TOOL_CONTENT_ID)); - } + return activity; + } - if (keyExists(activityDetails, WDDXTAGS.TOOL_ID)) { - Tool tool = toolDAO.getToolByID(WDDXProcessor.convertToLong( - activityDetails, WDDXTAGS.TOOL_ID)); - toolActivity.setTool(tool); - } + private Integer getCoord(Hashtable details, String wddxtag) throws WDDXProcessorConversionException { + Integer coord = null; + if (keyExists(details, wddxtag)) { + coord = WDDXProcessor.convertToInteger(details, wddxtag); } + return coord == null || coord >= 0 ? coord : ObjectExtractor.DEFAULT_COORD; + } - private void buildGateActivity(Object activity, Hashtable activityDetails) - throws WDDXProcessorConversionException { - if (activity instanceof SynchGateActivity) { - buildSynchGateActivity((SynchGateActivity) activity, - activityDetails); - } - else if (activity instanceof PermissionGateActivity) { - buildPermissionGateActivity((PermissionGateActivity) activity, - activityDetails); - } - else if (activity instanceof SystemGateActivity) { - buildSystemGateActivity((SystemGateActivity) activity, - activityDetails); - } - else if (activity instanceof ConditionGateActivity) { - buildConditionGateActivity((ConditionGateActivity) activity, - activityDetails); - } - else { - buildScheduleGateActivity((ScheduleGateActivity) activity, - activityDetails); - } - GateActivity gateActivity = (GateActivity) activity; - gateActivity.setGateActivityLevelId(WDDXProcessor.convertToInteger( - activityDetails, WDDXTAGS.GATE_ACTIVITY_LEVEL_ID)); - gateActivity.setGateOpen(WDDXProcessor.convertToBoolean( - activityDetails, WDDXTAGS.GATE_OPEN)); + private void clearGrouping(Activity activity) { + activity.setGrouping(null); + activity.setGroupingUIID(null); + activity.setApplyGrouping(false); + } - } + private void setGrouping(Activity activity, Grouping grouping, Integer groupingUIID) { + activity.setGrouping(grouping); + activity.setGroupingUIID(groupingUIID); + activity.setApplyGrouping(true); + } - private void buildSynchGateActivity(SynchGateActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - activity.setSystemTool(getSystemTool(SystemTool.SYNC_GATE)); + private void processActivityType(Activity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException, ObjectExtractorException { + if (activity.isGroupingActivity()) { + buildGroupingActivity((GroupingActivity) activity, activityDetails); + } else if (activity.isToolActivity()) { + buildToolActivity((ToolActivity) activity, activityDetails); + } else if (activity.isGateActivity()) { + buildGateActivity(activity, activityDetails); + } else { + buildComplexActivity((ComplexActivity) activity, activityDetails); } + } - private void buildPermissionGateActivity(PermissionGateActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - activity.setSystemTool(getSystemTool(SystemTool.PERMISSION_GATE)); - } + private void buildComplexActivity(ComplexActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException, ObjectExtractorException { + // clear all the children - will be built up again by + // parseActivitiesToMatchUpParentActivityByParentUIID + // we don't use all-delete-orphan on the activities relationship so we + // can do this clear. + activity.getActivities().clear(); - private void buildSystemGateActivity(SystemGateActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - activity.setSystemTool(getSystemTool(SystemTool.SYSTEM_GATE)); + activity.setDefaultActivity(null); + Integer defaultActivityMapUIID = WDDXProcessor + .convertToInteger(activityDetails, WDDXTAGS.DEFAULT_ACTIVITY_UIID); + if (defaultActivityMapUIID != null) { + defaultActivityMap.put(defaultActivityMapUIID, activity); } - private void buildScheduleGateActivity(ScheduleGateActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - // activity.setGateStartDateTime(WDDXProcessor.convertToDate(activityDetails,WDDXTAGS.GATE_START_DATE)); - // activity.setGateEndDateTime(WDDXProcessor.convertToDate(activityDetails,WDDXTAGS.GATE_END_DATE)); - activity.setGateStartTimeOffset(WDDXProcessor.convertToLong( - activityDetails, WDDXTAGS.GATE_START_OFFSET)); - activity.setGateEndTimeOffset(WDDXProcessor.convertToLong( - activityDetails, WDDXTAGS.GATE_END_OFFSET)); - SystemTool systemTool = getSystemTool(SystemTool.SCHEDULE_GATE); - activity.setSystemTool(systemTool); + if (activity instanceof OptionsActivity) { + buildOptionsActivity((OptionsActivity) activity, activityDetails); + } else if (activity instanceof ParallelActivity) { + buildParallelActivity((ParallelActivity) activity, activityDetails); + } else if (activity instanceof BranchingActivity) { + buildBranchingActivity((BranchingActivity) activity, activityDetails); + } else { + buildSequenceActivity((SequenceActivity) activity, activityDetails); } + } - private void createLessonClass(LessonClass lessonClass, - Hashtable groupingDetails) throws WDDXProcessorConversionException { - if (keyExists(groupingDetails, WDDXTAGS.STAFF_GROUP_ID)) { - Group group = groupDAO.getGroupById(WDDXProcessor.convertToLong( - groupingDetails, WDDXTAGS.STAFF_GROUP_ID)); - if (group != null) { - lessonClass.setStaffGroup(group); - } - } + private void buildBranchingActivity(BranchingActivity branchingActivity, Hashtable activityDetails) + throws WDDXProcessorConversionException, ObjectExtractorException { + if (branchingActivity.isChosenBranchingActivity()) { + branchingActivity.setSystemTool(getSystemTool(SystemTool.TEACHER_CHOSEN_BRANCHING)); + } else if (branchingActivity.isGroupBranchingActivity()) { + branchingActivity.setSystemTool(getSystemTool(SystemTool.GROUP_BASED_BRANCHING)); + } else if (branchingActivity.isToolBranchingActivity()) { + branchingActivity.setSystemTool(getSystemTool(SystemTool.TOOL_BASED_BRANCHING)); } + branchingActivity.setStartXcoord(getCoord(activityDetails, WDDXTAGS.START_XCOORD)); + branchingActivity.setStartYcoord(getCoord(activityDetails, WDDXTAGS.START_YCOORD)); + branchingActivity.setEndXcoord(getCoord(activityDetails, WDDXTAGS.END_XCOORD)); + branchingActivity.setEndYcoord(getCoord(activityDetails, WDDXTAGS.END_YCOORD)); + } + + private void buildGroupingActivity(GroupingActivity groupingActivity, Hashtable activityDetails) + throws WDDXProcessorConversionException, ObjectExtractorException { /** - * 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. - * - * @param transitionDetails - * @throws WDDXProcessorConversionException + * read the createGroupingUUID, get the Grouping Object, and set CreateGrouping to that object */ - private Transition extractTransitionObject(Hashtable transitionDetails) - throws WDDXProcessorConversionException { + Integer createGroupingUIID = WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.CREATE_GROUPING_UIID); + Grouping grouping = groupings.get(createGroupingUIID); + if (grouping != null) { + groupingActivity.setCreateGrouping(grouping); + groupingActivity.setCreateGroupingUIID(createGroupingUIID); + } - Integer transitionUUID = WDDXProcessor.convertToInteger( - transitionDetails, WDDXTAGS.TRANSITION_UIID); - if (transitionUUID == null) { - throw new WDDXProcessorConversionException( - "Transition is missing its UUID " + transitionDetails); - } + SystemTool systemTool = getSystemTool(SystemTool.GROUPING); + groupingActivity.setSystemTool(systemTool); - Integer toUIID = WDDXProcessor.convertToInteger(transitionDetails, - WDDXTAGS.TO_ACTIVITY_UIID); - if (toUIID == null) { - throw new WDDXProcessorConversionException( - "Transition is missing its toUUID " + transitionDetails); - } + /* + * Hashtable groupingDetails = (Hashtable) activityDetails.get(WDDXTAGS.GROUPING_DTO); if( groupingDetails != + * null ){ Grouping grouping = extractGroupingObject(groupingDetails); + * groupingActivity.setCreateGrouping(grouping); + * groupingActivity.setCreateGroupingUIID(grouping.getGroupingUIID()); } else { + * groupingActivity.setCreateGrouping(null); groupingActivity.setCreateGroupingUIID(null); } + */ + } - Integer fromUIID = WDDXProcessor.convertToInteger(transitionDetails, - WDDXTAGS.FROM_ACTIVITY_UIID); - if (fromUIID == null) { - throw new WDDXProcessorConversionException( - "Transition is missing its fromUUID " + transitionDetails); - } + private void buildOptionsActivity(OptionsActivity optionsActivity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + if (keyExists(activityDetails, WDDXTAGS.MAX_OPTIONS)) { + optionsActivity + .setMaxNumberOfOptions(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.MAX_OPTIONS)); + } + if (keyExists(activityDetails, WDDXTAGS.MIN_OPTIONS)) { + optionsActivity + .setMinNumberOfOptions(WDDXProcessor.convertToInteger(activityDetails, WDDXTAGS.MIN_OPTIONS)); + } + if (keyExists(activityDetails, WDDXTAGS.OPTIONS_INSTRUCTIONS)) { + optionsActivity.setOptionsInstructions(WDDXProcessor.convertToString(activityDetails, + WDDXTAGS.OPTIONS_INSTRUCTIONS)); + } + } - Transition transition = null; - Transition existingTransition = findTransition(transitionUUID, toUIID, - fromUIID); + private void buildParallelActivity(ParallelActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + } - if (existingTransition == null) { - transition = new Transition(); - } - else { - transition = existingTransition; - } + private void buildSequenceActivity(SequenceActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + activity.setSystemTool(getSystemTool(SystemTool.SEQUENCE)); + } - transition.setTransitionUIID(transitionUUID); + private void buildToolActivity(ToolActivity toolActivity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + if (log.isDebugEnabled()) { + log.debug("In tool activity UUID" + activityDetails.get(WDDXTAGS.ACTIVITY_UIID) + " tool content id=" + + activityDetails.get(WDDXTAGS.TOOL_CONTENT_ID)); + } + if (keyExists(activityDetails, WDDXTAGS.TOOL_CONTENT_ID)) { + toolActivity.setToolContentId(WDDXProcessor.convertToLong(activityDetails, WDDXTAGS.TOOL_CONTENT_ID)); + } - Activity toActivity = newActivityMap.get(toUIID); - if (toActivity != null) { - transition.setToActivity(toActivity); - transition.setToUIID(toUIID); - // update the transitionTo property for the activity - toActivity.setTransitionTo(transition); - } - else { - transition.setToActivity(null); - transition.setToUIID(null); - } + if (keyExists(activityDetails, WDDXTAGS.TOOL_ID)) { + Tool tool = toolDAO.getToolByID(WDDXProcessor.convertToLong(activityDetails, WDDXTAGS.TOOL_ID)); + toolActivity.setTool(tool); + } + } - Activity fromActivity = newActivityMap.get(fromUIID); - if (fromActivity != null) { - transition.setFromActivity(fromActivity); - transition.setFromUIID(fromUIID); - // update the transitionFrom property for the activity - fromActivity.setTransitionFrom(transition); - } - else { - transition.setFromActivity(null); - transition.setFromUIID(null); - } + private void buildGateActivity(Object activity, Hashtable activityDetails) throws WDDXProcessorConversionException { + if (activity instanceof SynchGateActivity) { + buildSynchGateActivity((SynchGateActivity) activity, activityDetails); + } else if (activity instanceof PermissionGateActivity) { + buildPermissionGateActivity((PermissionGateActivity) activity, activityDetails); + } else if (activity instanceof SystemGateActivity) { + buildSystemGateActivity((SystemGateActivity) activity, activityDetails); + } else if (activity instanceof ConditionGateActivity) { + buildConditionGateActivity((ConditionGateActivity) activity, activityDetails); + } else { + buildScheduleGateActivity((ScheduleGateActivity) activity, activityDetails); + } + GateActivity gateActivity = (GateActivity) activity; + gateActivity.setGateActivityLevelId(WDDXProcessor.convertToInteger(activityDetails, + WDDXTAGS.GATE_ACTIVITY_LEVEL_ID)); + gateActivity.setGateOpen(WDDXProcessor.convertToBoolean(activityDetails, WDDXTAGS.GATE_OPEN)); - transition.setDescription(WDDXProcessor.convertToString( - transitionDetails, WDDXTAGS.DESCRIPTION)); - transition.setTitle(WDDXProcessor.convertToString(transitionDetails, - WDDXTAGS.TITLE)); + } - // Set creation date based on the server timezone, not the client. - if (transition.getCreateDateTime() == null) { - transition.setCreateDateTime(modificationDate); - } + private void buildSynchGateActivity(SynchGateActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + activity.setSystemTool(getSystemTool(SystemTool.SYNC_GATE)); + } - if (transition.getToActivity() != null - && transition.getFromActivity() != null) { - transition.setLearningDesign(learningDesign); - return transition; - } - else { - // One of the to/from is missing, can't store this transition. Make - // sure we clean up the related activities - cleanupTransition(transition); - transition.setLearningDesign(null); - return null; - } + private void buildPermissionGateActivity(PermissionGateActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + activity.setSystemTool(getSystemTool(SystemTool.PERMISSION_GATE)); + } + + private void buildSystemGateActivity(SystemGateActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + activity.setSystemTool(getSystemTool(SystemTool.SYSTEM_GATE)); + } + + private void buildScheduleGateActivity(ScheduleGateActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + // activity.setGateStartDateTime(WDDXProcessor.convertToDate(activityDetails,WDDXTAGS.GATE_START_DATE)); + // activity.setGateEndDateTime(WDDXProcessor.convertToDate(activityDetails,WDDXTAGS.GATE_END_DATE)); + activity.setGateStartTimeOffset(WDDXProcessor.convertToLong(activityDetails, WDDXTAGS.GATE_START_OFFSET)); + activity.setGateEndTimeOffset(WDDXProcessor.convertToLong(activityDetails, WDDXTAGS.GATE_END_OFFSET)); + SystemTool systemTool = getSystemTool(SystemTool.SCHEDULE_GATE); + activity.setSystemTool(systemTool); + } + + private void createLessonClass(LessonClass lessonClass, Hashtable groupingDetails) + throws WDDXProcessorConversionException { + if (keyExists(groupingDetails, WDDXTAGS.STAFF_GROUP_ID)) { + Group group = groupDAO.getGroupById(WDDXProcessor.convertToLong(groupingDetails, WDDXTAGS.STAFF_GROUP_ID)); + if (group != null) { + lessonClass.setStaffGroup(group); + } } + } - /** - * 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)) { - transition.getFromActivity().setTransitionFrom(null); - } - if (transition.getToActivity().getTransitionTo().equals(transition)) { - transition.getToActivity().setTransitionTo(null); - } + /** + * 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. + * + * @param transitionDetails + * @throws WDDXProcessorConversionException + */ + private Transition extractTransitionObject(Hashtable transitionDetails) throws WDDXProcessorConversionException { + + Integer transitionUUID = WDDXProcessor.convertToInteger(transitionDetails, WDDXTAGS.TRANSITION_UIID); + if (transitionUUID == null) { + throw new WDDXProcessorConversionException("Transition is missing its UUID " + transitionDetails); } - /** - * 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. - */ - private Transition findTransition(Integer transitionUUID, Integer toUIID, - Integer fromUIID) { - Transition existingTransition = null; - Set transitions = learningDesign.getTransitions(); - Iterator iter = transitions.iterator(); - while (existingTransition == null && iter.hasNext()) { - Transition element = (Transition) iter.next(); - if (transitionUUID != null - && transitionUUID.equals(element.getTransitionUIID())) { - existingTransition = element; - } - else if (toUIID != null && toUIID.equals(element.getToUIID()) - && fromUIID != null - && fromUIID.equals(element.getFromUIID())) { - existingTransition = element; - } - } - return existingTransition; + Integer toUIID = WDDXProcessor.convertToInteger(transitionDetails, WDDXTAGS.TO_ACTIVITY_UIID); + if (toUIID == null) { + throw new WDDXProcessorConversionException("Transition is missing its toUUID " + transitionDetails); } - /** - * 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 - * @param key - * The key to find - * @return - */ - private boolean keyExists(Hashtable table, String key) { - if (table.containsKey(key)) { - return true; - } - else { - return false; - } + Integer fromUIID = WDDXProcessor.convertToInteger(transitionDetails, WDDXTAGS.FROM_ACTIVITY_UIID); + if (fromUIID == null) { + throw new WDDXProcessorConversionException("Transition is missing its fromUUID " + transitionDetails); } - public void setMode(Integer mode) { - this.mode = mode; + Transition transition = null; + Transition existingTransition = findTransition(transitionUUID, toUIID, fromUIID); + + if (existingTransition == null) { + transition = new Transition(); + } else { + transition = existingTransition; } - public Integer getMode() { - return mode; + transition.setTransitionUIID(transitionUUID); + + Activity toActivity = newActivityMap.get(toUIID); + if (toActivity != null) { + transition.setToActivity(toActivity); + transition.setToUIID(toUIID); + // update the transitionTo property for the activity + toActivity.setTransitionTo(transition); + } else { + transition.setToActivity(null); + transition.setToUIID(null); } - /** - * 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. - * - * Will also delete any old (now unused) mappings - * - * @param branchMappingsList - * @throws WDDXProcessorConversionException - */ + Activity fromActivity = newActivityMap.get(fromUIID); + if (fromActivity != null) { + transition.setFromActivity(fromActivity); + transition.setFromUIID(fromUIID); + // update the transitionFrom property for the activity + fromActivity.setTransitionFrom(transition); + } else { + transition.setFromActivity(null); + transition.setFromUIID(null); + } - private void parseBranchMappings(List branchMappingsList) - throws WDDXProcessorConversionException { - if (branchMappingsList != null) { - Iterator iterator = branchMappingsList.iterator(); - while (iterator.hasNext()) { - extractBranchActivityEntry((Hashtable) iterator.next()); - } - } + transition.setDescription(WDDXProcessor.convertToString(transitionDetails, WDDXTAGS.DESCRIPTION)); + transition.setTitle(WDDXProcessor.convertToString(transitionDetails, WDDXTAGS.TITLE)); - // now go through and delete any old branch mappings that are no longer - // used. - // need to remove them from their collections to make sure it isn't - // accidently re-added. - Iterator iter = oldbranchActivityEntryList.iterator(); - while (iter.hasNext()) { - BranchActivityEntry oldEntry = (BranchActivityEntry) iter.next(); - SequenceActivity sequenceActivity = oldEntry - .getBranchSequenceActivity(); - if (sequenceActivity != null) { - sequenceActivity.getBranchEntries().remove(oldEntry); - } - Group group = oldEntry.getGroup(); - if (group != null) { - group.getBranchActivities().remove(oldEntry); - } - activityDAO.delete(oldEntry); - } + // Set creation date based on the server timezone, not the client. + if (transition.getCreateDateTime() == null) { + transition.setCreateDateTime(modificationDate); } - @SuppressWarnings("unchecked") - /** - * 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 { + if (transition.getToActivity() != null && transition.getFromActivity() != null) { + transition.setLearningDesign(learningDesign); + return transition; + } else { + // One of the to/from is missing, can't store this transition. Make + // sure we clean up the related activities + cleanupTransition(transition); + transition.setLearningDesign(null); + return null; + } + } - Long entryId = WDDXProcessor.convertToLong(details, - WDDXTAGS.BRANCH_ACTIVITY_ENTRY_ID); - Integer entryUIID = WDDXProcessor.convertToInteger(details, - WDDXTAGS.BRANCH_ACTIVITY_ENTRY_UIID); - if (entryUIID == null) { - throw new WDDXProcessorConversionException( - "Group based branch mapping entry is missing its UUID. Entry " - + details); - } + /** + * 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)) { + transition.getFromActivity().setTransitionFrom(null); + } + if (transition.getToActivity().getTransitionTo().equals(transition)) { + transition.getToActivity().setTransitionTo(null); + } + } - Integer sequenceActivityUIID = WDDXProcessor.convertToInteger(details, - WDDXTAGS.BRANCH_SEQUENCE_ACTIVITY_UIID); - Integer branchingActivityUIID = WDDXProcessor.convertToInteger(details, - WDDXTAGS.BRANCH_ACTIVITY_UIID); + /** + * 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. + */ + private Transition findTransition(Integer transitionUUID, Integer toUIID, Integer fromUIID) { + Transition existingTransition = null; + Set transitions = learningDesign.getTransitions(); + Iterator iter = transitions.iterator(); + while (existingTransition == null && iter.hasNext()) { + Transition element = (Transition) iter.next(); + if (transitionUUID != null && transitionUUID.equals(element.getTransitionUIID())) { + existingTransition = element; + } else if (toUIID != null && toUIID.equals(element.getToUIID()) && fromUIID != null + && fromUIID.equals(element.getFromUIID())) { + existingTransition = element; + } + } + return existingTransition; + } - Activity branchingActivity = newActivityMap.get(branchingActivityUIID); - if (branchingActivity == null) { - throw new WDDXProcessorConversionException( - "Branching Activity listed in the branch mapping list is missing. Mapping entry UUID " - + entryUIID - + " branchingActivityUIID " - + branchingActivityUIID); - } - if (!branchingActivity.isBranchingActivity() - && !branchingActivity.isConditionGate()) { - throw new WDDXProcessorConversionException( - "Activity listed in the branch mapping list is not a branching activity nor a condition gate. Mapping entry UUID " - + entryUIID - + " branchingActivityUIID " - + branchingActivityUIID); - } - // sequence activity is null for a condition gate - SequenceActivity sequenceActivity = null; - if (!branchingActivity.isConditionGate()) { - Activity activity = newActivityMap.get(sequenceActivityUIID); - if (activity == null) { - throw new WDDXProcessorConversionException( - "Sequence Activity listed in the branch mapping list is missing. Mapping entry UUID " - + entryUIID - + " sequenceActivityUIID " - + sequenceActivityUIID); - } - else if (!activity.isSequenceActivity()) { - throw new WDDXProcessorConversionException( - "Activity listed in the branch mapping list is not a sequence activity. Mapping entry UUID " - + entryUIID - + " sequenceActivityUIID " - + sequenceActivityUIID); - } - else { - sequenceActivity = (SequenceActivity) activity; - } - } + /** + * 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 + * @param key + * The key to find + * @return + */ + private boolean keyExists(Hashtable table, String key) { + if (table.containsKey(key)) { + return true; + } else { + return false; + } + } - // If the mapping was created at runtime, there will be an ID but no IU - // ID field. - // If it was created in authoring, will have a UI ID and may or may not - // have an ID. - // So try to match up on UI ID first, failing that match on ID. Then the - // worst case, which is the mapping - // is created at runtime but then modified in authoring (and has has a - // new UI ID added) is handled. - BranchActivityEntry uiid_match = null; - BranchActivityEntry id_match = null; - Iterator iter = null; - if (sequenceActivity != null) { - if (sequenceActivity.getBranchEntries() != null) { - iter = sequenceActivity.getBranchEntries().iterator(); - } - } - else { - iter = ((ConditionGateActivity) branchingActivity) - .getOpeningGateBranchEntries().iterator(); - } + public void setMode(Integer mode) { + this.mode = mode; + } - if (iter != null) { - while (uiid_match == null && iter.hasNext()) { - BranchActivityEntry possibleEntry = (BranchActivityEntry) iter - .next(); - if (entryUIID.equals(possibleEntry.getEntryUIID())) { - uiid_match = possibleEntry; - } - if (entryId != null - && entryId.equals(possibleEntry.getEntryId())) { - id_match = possibleEntry; - } - } - } + public Integer getMode() { + return mode; + } - BranchActivityEntry entry = uiid_match != null ? uiid_match : id_match; + /** + * 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. + * + * Will also delete any old (now unused) mappings + * + * @param branchMappingsList + * @throws WDDXProcessorConversionException + */ - // Does it exist already? If it does, remove it from the "old" set - // (which is used for doing deletions later). - oldbranchActivityEntryList.remove(entry); + private void parseBranchMappings(List branchMappingsList) throws WDDXProcessorConversionException { + if (branchMappingsList != null) { + Iterator iterator = branchMappingsList.iterator(); + while (iterator.hasNext()) { + extractBranchActivityEntry((Hashtable) iterator.next()); + } + } - BranchCondition condition = extractCondition((Hashtable) details - .get(WDDXTAGS.BRANCH_CONDITION), entry); + // now go through and delete any old branch mappings that are no longer + // used. + // need to remove them from their collections to make sure it isn't + // accidently re-added. + Iterator iter = oldbranchActivityEntryList.iterator(); + while (iter.hasNext()) { + BranchActivityEntry oldEntry = (BranchActivityEntry) iter.next(); + SequenceActivity sequenceActivity = oldEntry.getBranchSequenceActivity(); + if (sequenceActivity != null) { + sequenceActivity.getBranchEntries().remove(oldEntry); + } + Group group = oldEntry.getGroup(); + if (group != null) { + group.getBranchActivities().remove(oldEntry); + } + activityDAO.delete(oldEntry); + } + } - Integer groupUIID = WDDXProcessor.convertToInteger(details, - WDDXTAGS.GROUP_UIID); - Group group = null; - if (groupUIID != null) { - group = groups.get(groupUIID); - if (group == null) { - throw new WDDXProcessorConversionException( - "Group listed in the branch mapping list is missing. Mapping entry UUID " - + entryUIID + " groupUIID " + groupUIID); - } - } + @SuppressWarnings("unchecked") + /** + * 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 { - if (condition == null && group == null) { - throw new WDDXProcessorConversionException( - "Branch mapping has neither a group or a condition. Not a valid mapping. " - + details); - } + Long entryId = WDDXProcessor.convertToLong(details, WDDXTAGS.BRANCH_ACTIVITY_ENTRY_ID); + Integer entryUIID = WDDXProcessor.convertToInteger(details, WDDXTAGS.BRANCH_ACTIVITY_ENTRY_UIID); + if (entryUIID == null) { + throw new WDDXProcessorConversionException("Group based branch mapping entry is missing its UUID. Entry " + + details); + } - if (entry == null) { - if (condition != null) { - entry = condition.allocateBranchToCondition(entryUIID, - sequenceActivity, branchingActivity); - } - else { - entry = group - .allocateBranchToGroup(entryUIID, sequenceActivity, - (BranchingActivity) branchingActivity); - } - } - else { - entry.setEntryUIID(entryUIID); - entry.setBranchSequenceActivity(sequenceActivity); - entry.setBranchingActivity(branchingActivity); - } + Integer sequenceActivityUIID = WDDXProcessor.convertToInteger(details, WDDXTAGS.BRANCH_SEQUENCE_ACTIVITY_UIID); + Integer branchingActivityUIID = WDDXProcessor.convertToInteger(details, WDDXTAGS.BRANCH_ACTIVITY_UIID); - entry.setGroup(group); - entry.setCondition(condition); - if (sequenceActivity != null) { - if (sequenceActivity.getBranchEntries() == null) { - sequenceActivity.setBranchEntries(new HashSet()); - } - sequenceActivity.getBranchEntries().add(entry); - activityDAO.update(sequenceActivity); - } + Activity branchingActivity = newActivityMap.get(branchingActivityUIID); + if (branchingActivity == null) { + throw new WDDXProcessorConversionException( + "Branching Activity listed in the branch mapping list is missing. Mapping entry UUID " + entryUIID + + " branchingActivityUIID " + branchingActivityUIID); + } + if (!branchingActivity.isBranchingActivity() && !branchingActivity.isConditionGate()) { + throw new WDDXProcessorConversionException( + "Activity listed in the branch mapping list is not a branching activity nor a condition gate. Mapping entry UUID " + + entryUIID + " branchingActivityUIID " + branchingActivityUIID); + } + // sequence activity is null for a condition gate + SequenceActivity sequenceActivity = null; + if (!branchingActivity.isConditionGate()) { + Activity activity = newActivityMap.get(sequenceActivityUIID); + if (activity == null) { + throw new WDDXProcessorConversionException( + "Sequence Activity listed in the branch mapping list is missing. Mapping entry UUID " + + entryUIID + " sequenceActivityUIID " + sequenceActivityUIID); + } else if (!activity.isSequenceActivity()) { + throw new WDDXProcessorConversionException( + "Activity listed in the branch mapping list is not a sequence activity. Mapping entry UUID " + + entryUIID + " sequenceActivityUIID " + sequenceActivityUIID); + } else { + sequenceActivity = (SequenceActivity) activity; + } + } - if (group != null) { - groupingDAO.update(group); - } + // If the mapping was created at runtime, there will be an ID but no IU + // ID field. + // If it was created in authoring, will have a UI ID and may or may not + // have an ID. + // So try to match up on UI ID first, failing that match on ID. Then the + // worst case, which is the mapping + // is created at runtime but then modified in authoring (and has has a + // new UI ID added) is handled. + BranchActivityEntry uiid_match = null; + BranchActivityEntry id_match = null; + Iterator iter = null; + if (sequenceActivity != null) { + if (sequenceActivity.getBranchEntries() != null) { + iter = sequenceActivity.getBranchEntries().iterator(); + } + } else { + iter = ((ConditionGateActivity) branchingActivity).getOpeningGateBranchEntries().iterator(); + } - return entry; + if (iter != null) { + while (uiid_match == null && iter.hasNext()) { + BranchActivityEntry possibleEntry = (BranchActivityEntry) iter.next(); + if (entryUIID.equals(possibleEntry.getEntryUIID())) { + uiid_match = possibleEntry; + } + if (entryId != null && entryId.equals(possibleEntry.getEntryId())) { + id_match = possibleEntry; + } + } } - /** - * @param details - * @param entry - * @return - * @throws WDDXProcessorConversionException - */ - private BranchCondition extractCondition(Hashtable conditionTable, - BranchActivityEntry entry) throws WDDXProcessorConversionException { + BranchActivityEntry entry = uiid_match != null ? uiid_match : id_match; - BranchCondition condition = null; + // Does it exist already? If it does, remove it from the "old" set + // (which is used for doing deletions later). + oldbranchActivityEntryList.remove(entry); - if (conditionTable != null && conditionTable.size() > 0) { + BranchCondition condition = extractCondition((Hashtable) details.get(WDDXTAGS.BRANCH_CONDITION), entry); - Long conditionID = WDDXProcessor.convertToLong(conditionTable, - WDDXTAGS.CONDITION_ID); - if (entry != null) { - condition = entry.getCondition(); - } - if (condition != null && conditionID != null - && !condition.getConditionId().equals(conditionID)) { - log - .warn("Unexpected behaviour: condition supplied in WDDX packet has a different ID to matching branch activity entry in the database. Dropping old database condition." - + " Old db condition " - + condition - + " new entry in WDDX " + conditionTable); - condition = null; // Hibernate should dispose of it - // automatically via the cascade - } + Integer groupUIID = WDDXProcessor.convertToInteger(details, WDDXTAGS.GROUP_UIID); + Group group = null; + if (groupUIID != null) { + group = groups.get(groupUIID); + if (group == null) { + throw new WDDXProcessorConversionException( + "Group listed in the branch mapping list is missing. Mapping entry UUID " + entryUIID + + " groupUIID " + groupUIID); + } + } - Integer conditionUIID = WDDXProcessor.convertToInteger( - conditionTable, WDDXTAGS.CONDITION_UIID); - if (conditionUIID == null) { - throw new WDDXProcessorConversionException( - "Condition is missing its UUID: " + conditionTable); - } + if (condition == null && group == null) { + throw new WDDXProcessorConversionException( + "Branch mapping has neither a group or a condition. Not a valid mapping. " + details); + } - String endValue = WDDXProcessor.convertToString(conditionTable, - WDDXTAGS.CONDITION_END_VALUE); + if (entry == null) { + if (condition != null) { + entry = condition.allocateBranchToCondition(entryUIID, sequenceActivity, branchingActivity); + } else { + entry = group.allocateBranchToGroup(entryUIID, sequenceActivity, (BranchingActivity) branchingActivity); + } + } else { + entry.setEntryUIID(entryUIID); + entry.setBranchSequenceActivity(sequenceActivity); + entry.setBranchingActivity(branchingActivity); + } - if (condition == null) { - condition = new BranchCondition(null, conditionUIID, - WDDXProcessor.convertToInteger(conditionTable, - WDDXTAGS.ORDER_ID), WDDXProcessor - .convertToString(conditionTable, - WDDXTAGS.CONDITION_NAME), WDDXProcessor - .convertToString(conditionTable, - WDDXTAGS.CONDITION_DISPLAY_NAME), - WDDXProcessor.convertToString(conditionTable, - WDDXTAGS.CONDITION_TYPE), WDDXProcessor - .convertToString(conditionTable, - WDDXTAGS.CONDITION_START_VALUE), - endValue, WDDXProcessor.convertToString(conditionTable, - WDDXTAGS.CONDITION_EXACT_MATCH_VALUE)); - } - else { - condition.setConditionUIID(conditionUIID); - condition.setDisplayName(WDDXProcessor.convertToString( - conditionTable, WDDXTAGS.CONDITION_DISPLAY_NAME)); - condition.setEndValue(endValue); - condition.setExactMatchValue(WDDXProcessor.convertToString( - conditionTable, WDDXTAGS.CONDITION_EXACT_MATCH_VALUE)); - condition.setName(WDDXProcessor.convertToString(conditionTable, - WDDXTAGS.CONDITION_NAME)); - condition.setOrderId(WDDXProcessor.convertToInteger( - conditionTable, WDDXTAGS.ORDER_ID)); - condition.setStartValue(WDDXProcessor.convertToString( - conditionTable, WDDXTAGS.CONDITION_START_VALUE)); - condition.setType(WDDXProcessor.convertToString(conditionTable, - WDDXTAGS.CONDITION_TYPE)); - } - } - return condition; + entry.setGroup(group); + entry.setCondition(condition); + if (sequenceActivity != null) { + if (sequenceActivity.getBranchEntries() == null) { + sequenceActivity.setBranchEntries(new HashSet()); + } + sequenceActivity.getBranchEntries().add(entry); + activityDAO.update(sequenceActivity); } - private SystemTool getSystemTool(Long systemToolId) { - SystemTool tool = systemTools.get(systemToolId); - if (tool == null) { - tool = systemToolDAO.getSystemToolByID(systemToolId); - if (tool != null) { - systemTools.put(systemToolId, tool); - } - else { - log - .error("ObjectExtractor: Unable to find matching system tool for id " - + systemToolId); - } - } - return tool; + if (group != null) { + groupingDAO.update(group); } - private void createLearnerChoiceGrouping( - LearnerChoiceGrouping learnerChoiceGrouping, - Hashtable groupingDetails) throws WDDXProcessorConversionException { + return entry; + } - Integer numLearnersPerGroup = WDDXProcessor.convertToInteger( - groupingDetails, WDDXTAGS.LEARNERS_PER_GROUP); - if (numLearnersPerGroup != null && numLearnersPerGroup.intValue() > 0) { - learnerChoiceGrouping.setLearnersPerGroup(numLearnersPerGroup); - learnerChoiceGrouping.setNumberOfGroups(null); - learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(null); + /** + * @param details + * @param entry + * @return + * @throws WDDXProcessorConversionException + */ + private BranchCondition extractCondition(Hashtable conditionTable, BranchActivityEntry entry) + throws WDDXProcessorConversionException { + + BranchCondition condition = null; + + if (conditionTable != null && conditionTable.size() > 0) { + + Long conditionID = WDDXProcessor.convertToLong(conditionTable, WDDXTAGS.CONDITION_ID); + if (entry != null) { + condition = entry.getCondition(); + } + if (condition != null && conditionID != null && !condition.getConditionId().equals(conditionID)) { + log + .warn("Unexpected behaviour: condition supplied in WDDX packet has a different ID to matching branch activity entry in the database. Dropping old database condition." + + " Old db condition " + condition + " new entry in WDDX " + conditionTable); + condition = null; // Hibernate should dispose of it + // automatically via the cascade + } + + Integer conditionUIID = WDDXProcessor.convertToInteger(conditionTable, WDDXTAGS.CONDITION_UIID); + if (conditionUIID == null) { + throw new WDDXProcessorConversionException("Condition is missing its UUID: " + conditionTable); + } + String conditionType = WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_TYPE); + + if (BranchCondition.OUTPUT_TYPE_COMPLEX.equals(conditionType) + || BranchCondition.OUTPUT_TYPE_STRING.equals(conditionType)) { + if (condition == null) { + // This is different than "conditionID" !!! + Long newConditionID = WDDXProcessor.convertToLong(conditionTable, "conditionId"); + BranchCondition originalCondition = branchActivityEntryDAO.getConditionByID(newConditionID); + if (originalCondition == null) { + log.error("Could not find condition with given ID: " + conditionID); + } else { + condition = (BranchCondition) originalCondition.clone(); + condition.setConditionUIID(conditionUIID); + } } else { - Integer numGroups = WDDXProcessor.convertToInteger(groupingDetails, - WDDXTAGS.NUMBER_OF_GROUPS); - if (numGroups != null && numGroups.intValue() > 0) { - learnerChoiceGrouping.setNumberOfGroups(numGroups); - } - else { - learnerChoiceGrouping.setNumberOfGroups(null); - } - learnerChoiceGrouping.setLearnersPerGroup(null); - Boolean equalNumberOfLearnersPerGroup = WDDXProcessor - .convertToBoolean(groupingDetails, - WDDXTAGS.EQUAL_NUMBER_OF_LEARNERS_PER_GROUP); - if (equalNumberOfLearnersPerGroup != null) { - learnerChoiceGrouping - .setEqualNumberOfLearnersPerGroup(equalNumberOfLearnersPerGroup); - } + condition.setConditionUIID(conditionUIID); } + + } else if (condition == null) { + condition = new BranchCondition(null, conditionUIID, WDDXProcessor.convertToInteger(conditionTable, + WDDXTAGS.ORDER_ID), WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_NAME), + WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_DISPLAY_NAME), WDDXProcessor + .convertToString(conditionTable, WDDXTAGS.CONDITION_TYPE), WDDXProcessor + .convertToString(conditionTable, WDDXTAGS.CONDITION_START_VALUE), WDDXProcessor + .convertToString(conditionTable, WDDXTAGS.CONDITION_END_VALUE), WDDXProcessor + .convertToString(conditionTable, WDDXTAGS.CONDITION_EXACT_MATCH_VALUE)); + } else { + condition.setConditionUIID(conditionUIID); + condition + .setDisplayName(WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_DISPLAY_NAME)); + condition.setEndValue(WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_END_VALUE)); + condition.setExactMatchValue(WDDXProcessor.convertToString(conditionTable, + WDDXTAGS.CONDITION_EXACT_MATCH_VALUE)); + condition.setName(WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_NAME)); + condition.setOrderId(WDDXProcessor.convertToInteger(conditionTable, WDDXTAGS.ORDER_ID)); + condition.setStartValue(WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_START_VALUE)); + condition.setType(WDDXProcessor.convertToString(conditionTable, WDDXTAGS.CONDITION_TYPE)); + } } + return condition; + } - private void buildConditionGateActivity(ConditionGateActivity activity, - Hashtable activityDetails) throws WDDXProcessorConversionException { - activity.setSystemTool(getSystemTool(SystemTool.CONDITION_GATE)); + private SystemTool getSystemTool(Long systemToolId) { + SystemTool tool = systemTools.get(systemToolId); + if (tool == null) { + tool = systemToolDAO.getSystemToolByID(systemToolId); + if (tool != null) { + systemTools.put(systemToolId, tool); + } else { + log.error("ObjectExtractor: Unable to find matching system tool for id " + systemToolId); + } } + return tool; + } + + private void createLearnerChoiceGrouping(LearnerChoiceGrouping learnerChoiceGrouping, Hashtable groupingDetails) + throws WDDXProcessorConversionException { + + Integer numLearnersPerGroup = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.LEARNERS_PER_GROUP); + if (numLearnersPerGroup != null && numLearnersPerGroup.intValue() > 0) { + learnerChoiceGrouping.setLearnersPerGroup(numLearnersPerGroup); + learnerChoiceGrouping.setNumberOfGroups(null); + learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(null); + } else { + Integer numGroups = WDDXProcessor.convertToInteger(groupingDetails, WDDXTAGS.NUMBER_OF_GROUPS); + if (numGroups != null && numGroups.intValue() > 0) { + learnerChoiceGrouping.setNumberOfGroups(numGroups); + } else { + learnerChoiceGrouping.setNumberOfGroups(null); + } + learnerChoiceGrouping.setLearnersPerGroup(null); + Boolean equalNumberOfLearnersPerGroup = WDDXProcessor.convertToBoolean(groupingDetails, + WDDXTAGS.EQUAL_NUMBER_OF_LEARNERS_PER_GROUP); + if (equalNumberOfLearnersPerGroup != null) { + learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(equalNumberOfLearnersPerGroup); + } + } + } + + private void buildConditionGateActivity(ConditionGateActivity activity, Hashtable activityDetails) + throws WDDXProcessorConversionException { + activity.setSystemTool(getSystemTool(SystemTool.CONDITION_GATE)); + } } \ No newline at end of file Index: lams_common/.classpath =================================================================== diff -u -r3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/.classpath (.../.classpath) (revision 3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23) +++ lams_common/.classpath (.../.classpath) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -10,10 +10,6 @@ - - - - Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/BranchActivityEntry.hbm.xml =================================================================== diff -u -r3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/BranchActivityEntry.hbm.xml (.../BranchActivityEntry.hbm.xml) (revision 3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/BranchActivityEntry.hbm.xml (.../BranchActivityEntry.hbm.xml) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -38,7 +38,7 @@ - Index: lams_common/db/model/lams_11.clay =================================================================== diff -u -r44cd820aae2478d1f77a2008b90fcea6cab6baba -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/db/model/lams_11.clay (.../lams_11.clay) (revision 44cd820aae2478d1f77a2008b90fcea6cab6baba) +++ lams_common/db/model/lams_11.clay (.../lams_11.clay) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -1,18 +1,18 @@ - + - + - + - + - + @@ -25,7 +25,7 @@ - + @@ -38,26 +38,26 @@ - + - + - + - + @@ -66,17 +66,17 @@ - +
- + - + @@ -89,27 +89,27 @@ - + - +
- + - + @@ -122,27 +122,27 @@ - + - +
- - + + - + @@ -155,27 +155,27 @@ - + - +
- + - + @@ -188,7 +188,7 @@ - + @@ -201,26 +201,26 @@ - + - + - + - + @@ -233,7 +233,7 @@ - + @@ -246,7 +246,7 @@ - + @@ -259,7 +259,7 @@ - + @@ -272,7 +272,7 @@ - + @@ -285,7 +285,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -311,7 +311,7 @@ - + @@ -324,7 +324,7 @@ - + @@ -337,7 +337,7 @@ - + @@ -350,7 +350,7 @@ - + @@ -363,7 +363,7 @@ - + @@ -376,7 +376,7 @@ - + @@ -389,13 +389,13 @@ - + - + @@ -408,7 +408,7 @@ - + @@ -421,7 +421,7 @@ - + @@ -434,13 +434,13 @@ - + - + @@ -453,7 +453,7 @@ - + @@ -466,7 +466,7 @@ - + @@ -479,7 +479,7 @@ - + @@ -492,7 +492,7 @@ - + @@ -505,7 +505,7 @@ - + @@ -518,7 +518,7 @@ - + @@ -531,26 +531,26 @@ - + - + - + - + @@ -563,7 +563,7 @@ - + @@ -576,7 +576,7 @@ - + @@ -589,14 +589,14 @@ - + - + @@ -609,7 +609,7 @@ - + @@ -622,7 +622,7 @@ - + @@ -635,7 +635,7 @@ - + @@ -648,7 +648,7 @@ - + @@ -661,7 +661,7 @@ - + @@ -674,7 +674,7 @@ - + @@ -687,7 +687,7 @@ - + @@ -700,7 +700,7 @@ - + @@ -714,90 +714,90 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -806,33 +806,33 @@ - + - + - + - + - +
- + - + @@ -845,27 +845,27 @@ - + - +
- + - + @@ -878,7 +878,7 @@ - + @@ -891,20 +891,20 @@ - + - + - + @@ -917,7 +917,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -943,7 +943,7 @@ - + @@ -956,13 +956,13 @@ - + - + @@ -975,25 +975,25 @@ - + - + - + - + @@ -1006,13 +1006,13 @@ - + - + @@ -1032,7 +1032,7 @@ - + @@ -1045,7 +1045,7 @@ - + @@ -1058,7 +1058,7 @@ - + @@ -1071,26 +1071,26 @@ - + - + - + - + @@ -1103,7 +1103,7 @@ - + @@ -1116,7 +1116,7 @@ - + @@ -1130,41 +1130,41 @@ - + - + - + - + - + - + @@ -1173,25 +1173,25 @@ - + - + - +
- + - + @@ -1204,14 +1204,14 @@ - + - + @@ -1224,7 +1224,7 @@ - + @@ -1237,7 +1237,7 @@ - + @@ -1251,13 +1251,13 @@ - + - + @@ -1266,17 +1266,17 @@ - +
- - + + - + @@ -1289,7 +1289,7 @@ - + @@ -1302,7 +1302,7 @@ - + @@ -1315,7 +1315,7 @@ - + @@ -1328,7 +1328,7 @@ - + @@ -1341,7 +1341,7 @@ - + @@ -1354,7 +1354,7 @@ - + @@ -1368,13 +1368,13 @@ - + - + @@ -1383,17 +1383,17 @@ - +
- + - + @@ -1406,20 +1406,20 @@ - + - + - + @@ -1432,26 +1432,26 @@ - + - +
- + - + @@ -1464,7 +1464,7 @@ - + @@ -1477,20 +1477,20 @@ - + - + - + @@ -1503,7 +1503,7 @@ - + @@ -1516,7 +1516,7 @@ - + @@ -1529,13 +1529,13 @@ - + - + @@ -1548,7 +1548,7 @@ - + @@ -1562,33 +1562,33 @@ - + - + - + - + - + @@ -1597,25 +1597,25 @@ - + - + - +
- + - + @@ -1628,28 +1628,28 @@ - + - + - + - + @@ -1662,7 +1662,7 @@ - + @@ -1675,13 +1675,13 @@ - + - + @@ -1694,7 +1694,7 @@ - + @@ -1707,7 +1707,7 @@ - + @@ -1720,7 +1720,7 @@ - + @@ -1733,7 +1733,7 @@ - + @@ -1746,7 +1746,7 @@ - + @@ -1759,7 +1759,7 @@ - + @@ -1772,7 +1772,7 @@ - + @@ -1785,54 +1785,54 @@ - + - + - + - + - + - + - + - + @@ -1841,25 +1841,25 @@ - + - + - +
- + - + @@ -1872,39 +1872,39 @@ - + - + - + - +
- + - + @@ -1917,44 +1917,44 @@ - + - + - + - + - +
- + - + @@ -1967,126 +1967,126 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2099,13 +2099,13 @@ - + - + @@ -2118,7 +2118,7 @@ - + @@ -2131,7 +2131,7 @@ - + @@ -2144,7 +2144,7 @@ - + @@ -2157,14 +2157,14 @@ - + - + @@ -2177,7 +2177,7 @@ - + @@ -2190,7 +2190,7 @@ - + @@ -2203,13 +2203,13 @@ - + - + @@ -2223,41 +2223,41 @@ - + - + - + - + - + - + @@ -2266,33 +2266,33 @@ - + - + - + - + - +
- + - + @@ -2305,7 +2305,7 @@ - + @@ -2318,7 +2318,7 @@ - + @@ -2332,20 +2332,20 @@ - + - + - + @@ -2354,21 +2354,21 @@ - + - +
- + - + @@ -2381,7 +2381,7 @@ - + @@ -2394,7 +2394,7 @@ - + @@ -2408,20 +2408,20 @@ - + - + - + @@ -2430,21 +2430,21 @@ - + - +
- + - + @@ -2457,7 +2457,7 @@ - + @@ -2470,7 +2470,7 @@ - + @@ -2483,28 +2483,28 @@ - + - + - + - + @@ -2514,11 +2514,11 @@
- + - + @@ -2531,7 +2531,7 @@ - + @@ -2544,14 +2544,14 @@ - + - + @@ -2564,19 +2564,19 @@ - + - + - + @@ -2590,20 +2590,20 @@ - + - + - + @@ -2612,17 +2612,17 @@ - +
- + - + @@ -2635,7 +2635,7 @@ - + @@ -2648,7 +2648,7 @@ - + @@ -2661,26 +2661,26 @@ - + - + - + - + @@ -2693,7 +2693,7 @@ - + @@ -2706,7 +2706,7 @@ - + @@ -2719,31 +2719,31 @@ - + - + - + - + - + @@ -2756,7 +2756,7 @@ - + @@ -2769,7 +2769,7 @@ - + @@ -2782,7 +2782,7 @@ - + @@ -2796,41 +2796,41 @@ - + - + - + - + - + - + @@ -2840,11 +2840,11 @@
- + - + @@ -2857,7 +2857,7 @@ - + @@ -2870,7 +2870,7 @@ - + @@ -2883,7 +2883,7 @@ - + @@ -2896,7 +2896,7 @@ - + @@ -2909,19 +2909,19 @@ - + - + - + @@ -2934,7 +2934,7 @@ - + @@ -2947,7 +2947,7 @@ - + @@ -2960,7 +2960,7 @@ - + @@ -2974,41 +2974,41 @@ - + - + - + - + - + - + @@ -3017,18 +3017,18 @@ - +
- + - + @@ -3048,21 +3048,21 @@ - + - + - + @@ -3083,7 +3083,7 @@ - + @@ -3096,7 +3096,7 @@ - + @@ -3109,7 +3109,7 @@ - + @@ -3122,7 +3122,7 @@ - + @@ -3135,7 +3135,7 @@ - + @@ -3148,112 +3148,112 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -3267,29 +3267,29 @@ - + - + - + - + - + @@ -3299,11 +3299,11 @@
- + - + @@ -3316,7 +3316,7 @@ - + @@ -3329,7 +3329,7 @@ - + @@ -3342,7 +3342,7 @@ - + @@ -3355,7 +3355,7 @@ - + @@ -3368,13 +3368,13 @@ - + - + @@ -3387,7 +3387,7 @@ - + @@ -3400,61 +3400,61 @@ - + - + - + - + - + - + - + - + - + @@ -3464,11 +3464,11 @@
- + - + @@ -3481,7 +3481,7 @@ - + @@ -3495,21 +3495,21 @@ - + - + - + @@ -3519,11 +3519,11 @@
- + - + @@ -3536,7 +3536,7 @@ - + @@ -3550,21 +3550,21 @@ - + - + - + @@ -3574,11 +3574,11 @@
- + - + @@ -3591,27 +3591,27 @@ - + - +
- + - + @@ -3624,7 +3624,7 @@ - + @@ -3638,21 +3638,21 @@ - + - + - + @@ -3662,11 +3662,11 @@
- + - + @@ -3679,27 +3679,27 @@ - + - +
- + - + @@ -3712,7 +3712,7 @@ - + @@ -3726,13 +3726,13 @@ - + - + @@ -3742,11 +3742,11 @@
- + - + @@ -3759,7 +3759,7 @@ - + @@ -3772,7 +3772,7 @@ - + @@ -3786,19 +3786,19 @@ - + - + - + @@ -3808,11 +3808,11 @@
- + - + @@ -3825,7 +3825,7 @@ - + @@ -3839,19 +3839,19 @@ - + - + - + @@ -3861,11 +3861,11 @@
- + - + @@ -3878,27 +3878,27 @@ - + - +
- + - + @@ -3911,28 +3911,28 @@ - + - + - + - + @@ -3945,27 +3945,27 @@ - + - +
- + - + @@ -3978,27 +3978,27 @@ - + - +
- + - + @@ -4011,15 +4011,15 @@ - + - + @@ -4034,7 +4034,7 @@ - + @@ -4047,15 +4047,15 @@ - + - + @@ -4069,7 +4069,7 @@ - + @@ -4082,34 +4082,34 @@ - + - + - +
- + - + @@ -4122,7 +4122,7 @@ - + @@ -4135,7 +4135,7 @@ - + @@ -4149,20 +4149,20 @@ - + - + - + @@ -4179,7 +4179,7 @@ - + @@ -4192,7 +4192,7 @@ - + @@ -4205,7 +4205,7 @@ - + @@ -4218,13 +4218,13 @@ - + - + @@ -4238,13 +4238,13 @@ - + - + @@ -4254,11 +4254,11 @@
- + - + @@ -4271,7 +4271,7 @@ - + @@ -4284,21 +4284,21 @@ - + - + - + @@ -4312,13 +4312,13 @@ - + - + @@ -4332,7 +4332,7 @@ - + @@ -4345,7 +4345,7 @@ - + @@ -4358,27 +4358,27 @@ - + - + - + - + @@ -4391,7 +4391,7 @@ - + @@ -4405,13 +4405,13 @@ - + - + @@ -4421,11 +4421,11 @@
- + - + @@ -4438,27 +4438,27 @@ - + - +
- + - + @@ -4471,27 +4471,27 @@ - + - +
- + - + @@ -4504,7 +4504,7 @@ - + @@ -4517,7 +4517,7 @@ - + @@ -4530,13 +4530,13 @@ - + - + @@ -4549,21 +4549,21 @@ - + - + - + @@ -4573,11 +4573,11 @@
- + - + @@ -4590,27 +4590,27 @@ - + - +
- + - + @@ -4623,7 +4623,7 @@ - + @@ -4636,33 +4636,33 @@ - + - + - + - + - + @@ -4675,7 +4675,7 @@ - + @@ -4688,7 +4688,7 @@ - + @@ -4701,41 +4701,41 @@ - + - + - + - + - + - + @@ -4745,11 +4745,11 @@
- + - + @@ -4762,27 +4762,27 @@ - + - +
- + - + @@ -4795,21 +4795,21 @@ - + - + - + @@ -4822,7 +4822,7 @@ - + @@ -4835,21 +4835,21 @@ - + - + - + @@ -4859,11 +4859,11 @@
- + - + @@ -4876,7 +4876,7 @@ - + @@ -4889,28 +4889,28 @@ - + - + - + - + @@ -4924,13 +4924,13 @@ - + - + @@ -4946,7 +4946,7 @@ - + @@ -4959,7 +4959,7 @@ - + @@ -4973,13 +4973,13 @@ - + - + @@ -4993,7 +4993,7 @@ - + @@ -5019,92 +5019,92 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -5118,7 +5118,7 @@ - + @@ -5131,29 +5131,29 @@ - + - + - + - + @@ -5163,7 +5163,7 @@ - + @@ -5176,7 +5176,7 @@ - + @@ -5189,7 +5189,7 @@ - + @@ -5203,20 +5203,20 @@ - + - + - + @@ -5226,11 +5226,11 @@
- + - + @@ -5243,27 +5243,27 @@ - + - +
- + - + @@ -5276,7 +5276,7 @@ - + @@ -5289,7 +5289,7 @@ - + @@ -5303,20 +5303,20 @@ - + - + - + @@ -5326,11 +5326,11 @@
- + - + @@ -5343,55 +5343,55 @@ - + - + - + - + - + - +
- + - + @@ -5404,22 +5404,22 @@ - + - + - + @@ -5431,42 +5431,42 @@ - + - + - + - + - + - + @@ -5480,7 +5480,7 @@ - + @@ -5492,7 +5492,7 @@ - + @@ -5505,7 +5505,7 @@ - + @@ -5518,7 +5518,7 @@ - + @@ -5531,7 +5531,7 @@ - + @@ -5544,7 +5544,7 @@ - + @@ -5557,7 +5557,7 @@ - + @@ -5571,34 +5571,34 @@ - + - + - + - + - + @@ -5609,10 +5609,10 @@
A LAMS learning activity may have one or more input activities. - + - + @@ -5625,7 +5625,7 @@ - + @@ -5639,25 +5639,25 @@ - + - + - + - + @@ -5667,11 +5667,11 @@
- + - + @@ -5684,7 +5684,7 @@ - + @@ -5697,7 +5697,7 @@ - + @@ -5710,62 +5710,62 @@ - + - + - + - + - + - + - +
- + - + @@ -5778,7 +5778,7 @@ - + @@ -5792,13 +5792,13 @@ - + - + @@ -5808,11 +5808,11 @@
- + - + @@ -5825,7 +5825,7 @@ - + @@ -5838,38 +5838,38 @@ - + - + - + - +
- + - + @@ -5882,7 +5882,7 @@ - + @@ -5895,7 +5895,7 @@ - + @@ -5908,7 +5908,7 @@ - + @@ -5921,7 +5921,7 @@ - + @@ -5934,33 +5934,33 @@ - + - + - + - + - + @@ -5970,11 +5970,11 @@
- + - + @@ -5987,21 +5987,21 @@ - + - + - + @@ -6014,7 +6014,7 @@ - + @@ -6027,40 +6027,40 @@ - + - + - + - + - + - + @@ -6072,17 +6072,17 @@ - + - + - + @@ -6092,29 +6092,87 @@ - + - + - + - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Index: lams_common/src/java/org/lamsfoundation/lams/commonContext.xml =================================================================== diff -u -rf27e4add424636db794f56d68dddea0fc4e1d7d2 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision f27e4add424636db794f56d68dddea0fc4e1d7d2) +++ lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -15,74 +15,83 @@ - + - org/lamsfoundation/lams/usermanagement/AuthenticationMethod.hbm.xml - org/lamsfoundation/lams/usermanagement/AuthenticationMethodType.hbm.xml - org/lamsfoundation/lams/usermanagement/Organisation.hbm.xml - org/lamsfoundation/lams/usermanagement/OrganisationState.hbm.xml - org/lamsfoundation/lams/usermanagement/OrganisationType.hbm.xml - org/lamsfoundation/lams/usermanagement/Role.hbm.xml - org/lamsfoundation/lams/usermanagement/Privilege.hbm.xml - org/lamsfoundation/lams/usermanagement/RolePrivilege.hbm.xml - org/lamsfoundation/lams/usermanagement/User.hbm.xml - org/lamsfoundation/lams/usermanagement/ForgotPasswordRequest.hbm.xml - org/lamsfoundation/lams/usermanagement/UserOrganisation.hbm.xml - org/lamsfoundation/lams/usermanagement/UserOrganisationCollapsed.hbm.xml - org/lamsfoundation/lams/usermanagement/UserOrganisationRole.hbm.xml - org/lamsfoundation/lams/usermanagement/Workspace.hbm.xml - org/lamsfoundation/lams/usermanagement/WorkspaceFolder.hbm.xml - org/lamsfoundation/lams/usermanagement/WorkspaceWorkspaceFolder.hbm.xml - org/lamsfoundation/lams/usermanagement/SupportedLocale.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/AuthenticationMethod.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/AuthenticationMethodType.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/Organisation.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/OrganisationState.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/OrganisationType.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/Role.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/Privilege.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/RolePrivilege.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/User.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/ForgotPasswordRequest.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/UserOrganisation.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/UserOrganisationCollapsed.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/UserOrganisationRole.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/Workspace.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/WorkspaceFolder.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/WorkspaceWorkspaceFolder.hbm.xml + classpath:org/lamsfoundation/lams/usermanagement/SupportedLocale.hbm.xml - org/lamsfoundation/lams/learningdesign/Activity.hbm.xml - org/lamsfoundation/lams/learningdesign/BranchActivityEntry.hbm.xml - org/lamsfoundation/lams/learningdesign/BranchCondition.hbm.xml - org/lamsfoundation/lams/learningdesign/Group.hbm.xml - org/lamsfoundation/lams/learningdesign/Grouping.hbm.xml - org/lamsfoundation/lams/learningdesign/LearningDesign.hbm.xml - org/lamsfoundation/lams/learningdesign/Competence.hbm.xml - org/lamsfoundation/lams/learningdesign/CompetenceMapping.hbm.xml - org/lamsfoundation/lams/learningdesign/LearningLibrary.hbm.xml - org/lamsfoundation/lams/learningdesign/Transition.hbm.xml - org/lamsfoundation/lams/learningdesign/License.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/Activity.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/BranchActivityEntry.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/BranchCondition.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/Group.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/Grouping.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/LearningDesign.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/Competence.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/CompetenceMapping.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/LearningLibrary.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/Transition.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/License.hbm.xml - org/lamsfoundation/lams/lesson/LearnerProgress.hbm.xml - org/lamsfoundation/lams/lesson/Lesson.hbm.xml + classpath:org/lamsfoundation/lams/lesson/LearnerProgress.hbm.xml + classpath:org/lamsfoundation/lams/lesson/Lesson.hbm.xml - org/lamsfoundation/lams/tool/SystemTool.hbm.xml - org/lamsfoundation/lams/tool/Tool.hbm.xml - org/lamsfoundation/lams/tool/ToolContent.hbm.xml - org/lamsfoundation/lams/tool/ToolSession.hbm.xml - org/lamsfoundation/lams/tool/ToolImportSupport.hbm.xml + classpath:org/lamsfoundation/lams/tool/SystemTool.hbm.xml + classpath:org/lamsfoundation/lams/tool/Tool.hbm.xml + classpath:org/lamsfoundation/lams/tool/ToolContent.hbm.xml + classpath:org/lamsfoundation/lams/tool/ToolSession.hbm.xml + classpath:org/lamsfoundation/lams/tool/ToolImportSupport.hbm.xml - org/lamsfoundation/lams/workspace/WorkspaceFolderContent.hbm.xml + classpath:org/lamsfoundation/lams/workspace/WorkspaceFolderContent.hbm.xml - org/lamsfoundation/lams/themes/CSSProperty.hbm.xml - org/lamsfoundation/lams/themes/CSSStyle.hbm.xml - org/lamsfoundation/lams/themes/CSSThemeVisualElement.hbm.xml + classpath:org/lamsfoundation/lams/themes/CSSProperty.hbm.xml + classpath:org/lamsfoundation/lams/themes/CSSStyle.hbm.xml + classpath:org/lamsfoundation/lams/themes/CSSThemeVisualElement.hbm.xml - org/lamsfoundation/lams/notebook/model/NotebookEntry.hbm.xml + classpath:org/lamsfoundation/lams/notebook/model/NotebookEntry.hbm.xml - org/lamsfoundation/lams/events/Event.hbm.xml - org/lamsfoundation/lams/events/Subscription.hbm.xml + classpath:org/lamsfoundation/lams/events/Event.hbm.xml + classpath:org/lamsfoundation/lams/events/Subscription.hbm.xml - org/lamsfoundation/lams/config/ConfigurationItem.hbm.xml + classpath:org/lamsfoundation/lams/config/ConfigurationItem.hbm.xml - org/lamsfoundation/lams/integration/ExtServerOrgMap.hbm.xml - org/lamsfoundation/lams/integration/ExtCourseClassMap.hbm.xml - org/lamsfoundation/lams/integration/ExtUserUseridMap.hbm.xml + classpath:org/lamsfoundation/lams/integration/ExtServerOrgMap.hbm.xml + classpath:org/lamsfoundation/lams/integration/ExtCourseClassMap.hbm.xml + classpath:org/lamsfoundation/lams/integration/ExtUserUseridMap.hbm.xml + + + + classpath*:org/lamsfoundation/lams/tool/qa/*.hbm.xml + classpath:org/lamsfoundation/lams/tool/notebook/model/Notebook.hbm.xml + classpath:org/lamsfoundation/lams/tool/notebook/model/NotebookSession.hbm.xml + classpath:org/lamsfoundation/lams/tool/notebook/model/NotebookUser.hbm.xml + classpath:org/lamsfoundation/lams/tool/notebook/model/NotebookAttachment.hbm.xml + classpath:org/lamsfoundation/lams/tool/notebook/model/NotebookCondition.hbm.xml Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/BranchCondition.java =================================================================== diff -u -r3538b4ae424da479962e98b7528ad22b44cdd368 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/BranchCondition.java (.../BranchCondition.java) (revision 3538b4ae424da479962e98b7528ad22b44cdd368) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/BranchCondition.java (.../BranchCondition.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -41,6 +41,16 @@ */ public class BranchCondition implements Comparable { + public static final String OUTPUT_TYPE_STRING = "OUTPUT_STRING"; + + public static final String OUTPUT_TYPE_BOOLEAN = "OUTPUT_BOOLEAN"; + + public static final String OUTPUT_TYPE_DOUBLE = "OUTPUT_DOUBLE"; + + public static final String OUTPUT_TYPE_LONG = "OUTPUT_LONG"; + + public static final String OUTPUT_TYPE_COMPLEX = "OUTPUT_COMPLEX"; + private static Logger log = Logger.getLogger(BranchCondition.class); protected Long conditionId; @@ -211,6 +221,11 @@ exactMatchValue); } + @Override + public Object clone() { + return new BranchCondition(null, null, orderId, name, displayName, type, startValue, endValue, exactMatchValue); + } + public int compareTo(Object arg0) { BranchCondition other = (BranchCondition) arg0; return new CompareToBuilder().append(orderId, other.getOrderId()).append(conditionId, other.getConditionId()) @@ -243,47 +258,47 @@ } public boolean exactMatchMet(ToolOutputValue outputValue) { - if ("OUTPUT_LONG".equals(type)) { + if (BranchCondition.OUTPUT_TYPE_LONG.equals(type)) { Long exactMatchObj = exactMatchValue != null ? convertToLong(exactMatchValue) : null; Long actualValue = outputValue.getLong(); return actualValue != null && actualValue.equals(exactMatchObj); - } else if ("OUTPUT_DOUBLE".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_DOUBLE.equals(type)) { Double exactMatchObj = exactMatchValue != null ? Double.parseDouble(exactMatchValue) : null; Double actualValue = outputValue.getDouble(); return actualValue != null && actualValue.equals(exactMatchObj); - } else if ("OUTPUT_BOOLEAN".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_BOOLEAN.equals(type)) { Boolean exactMatchObj = exactMatchValue != null ? Boolean.parseBoolean(exactMatchValue) : null; Boolean actualValue = outputValue.getBoolean(); return actualValue != null && actualValue.equals(exactMatchObj); - } else if ("OUTPUT_STRING".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_STRING.equals(type)) { Double actualValue = outputValue.getDouble(); return actualValue != null && actualValue.equals(exactMatchValue); } return false; } public boolean inRange(ToolOutputValue outputValue) { - if ("OUTPUT_LONG".equals(type)) { + if (BranchCondition.OUTPUT_TYPE_LONG.equals(type)) { Long startValueLong = startValue != null ? convertToLong(startValue) : null; Long endValueLong = endValue != null ? convertToLong(endValue) : null; Long actualValue = outputValue.getLong(); return actualValue != null && (startValueLong == null || actualValue.compareTo(startValueLong) >= 0) && (endValueLong == null || actualValue.compareTo(endValueLong) <= 0); - } else if ("OUTPUT_DOUBLE".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_DOUBLE.equals(type)) { Double startValueDouble = startValue != null ? Double.parseDouble(startValue) : null; Double endValueDouble = endValue != null ? Double.parseDouble(endValue) : null; Double actualValue = outputValue.getDouble(); return actualValue != null && (startValueDouble == null || actualValue.compareTo(startValueDouble) >= 0) && (endValueDouble == null || actualValue.compareTo(endValueDouble) <= 0); - } else if ("OUTPUT_BOOLEAN".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_BOOLEAN.equals(type)) { // this is a nonsense, but we'll code it just in case. What order is a boolean? True greater than false? Boolean startValueBoolean = startValue != null ? Boolean.parseBoolean(startValue) : null; Boolean endValueBoolean = endValue != null ? Boolean.parseBoolean(endValue) : null; Boolean actualValue = outputValue.getBoolean(); return actualValue != null && (startValueBoolean == null || actualValue.compareTo(startValueBoolean) >= 0) && (endValueBoolean == null || actualValue.compareTo(endValueBoolean) <= 0); - } else if ("OUTPUT_STRING".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_STRING.equals(type)) { String actualValue = outputValue.getString(); return actualValue != null && (startValue == null || actualValue.compareTo(startValue) >= 0) && (endValue == null || actualValue.compareTo(endValue) <= 0); @@ -353,17 +368,16 @@ } private Comparable getTypedValue(String untypedValue) { - if ("OUTPUT_LONG".equals(type)) { + if (BranchCondition.OUTPUT_TYPE_LONG.equals(type)) { return convertToLong(untypedValue); - } else if ("OUTPUT_DOUBLE".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_DOUBLE.equals(type)) { return Double.parseDouble(untypedValue); - } else if ("OUTPUT_BOOLEAN".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_BOOLEAN.equals(type)) { return Boolean.parseBoolean(untypedValue); - } else if ("OUTPUT_STRING".equals(type)) { + } else if (BranchCondition.OUTPUT_TYPE_STRING.equals(type)) { return untypedValue; } else { return null; } } - -} +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchCondition.java =================================================================== diff -u -r3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchCondition.java (.../TextSearchCondition.java) (revision 3590714b9dfaa2eeee7dcacaa1e76db4f1f45d23) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchCondition.java (.../TextSearchCondition.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -24,9 +24,11 @@ package org.lamsfoundation.lams.learningdesign; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.learningdesign.dto.BranchConditionDTO; import org.lamsfoundation.lams.tool.ToolOutput; @@ -61,9 +63,25 @@ // ---- non-persistent fields ---------- /** - * Regular expression that divides a string into single words. + * Regular expression that divides a string into single words. The meaning is "one or more whitespace characters or + * beginnings of a line or ends of a line". */ - public static final String WORD_DELIMITER_REGEX = "\\s"; + private static final String WORD_DELIMITER_REGEX = "(?:\\s|$|^)+"; + /** + * Integer that sets flags for regex pattern matching. + */ + private static final int PATTERN_MATCHING_OPTIONS = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE + | Pattern.MULTILINE; + /** + * A regular expression pattern that matches HTML tags. + */ + public static final String HTML_TAG_REGEX = "\\<.*?>"; + /** + * A regular expression pattern that matches end-of-line HTML tags. If needed, it can extented to + * (?:
|
|
|
)
. Right now FCKeditor creates only the first option. + */ + public static final String BR_TAG_REGEX = "
"; + private static Logger log = Logger.getLogger(TextSearchCondition.class); /** * Were the strings provided by user parsed into practical collections of words. @@ -74,9 +92,10 @@ */ protected List allWordsCondition = new ArrayList(); /** - * Same as {@link #phrase}. Created for + * Property {@link #phrase} divided into words. Although we are looking for the whole phrase, spaces between words + * should be divided into something more regex'y. */ - protected String phraseCondition; + protected List phraseCondition; /** * Property {@link #anyWords} divided into words. */ @@ -153,7 +172,7 @@ return phrase; } - public String getPhraseCondition() { + public List getPhraseCondition() { return phraseCondition; } @@ -163,8 +182,7 @@ } /** - * Checks if the given text contain the words provided in the condition parameters. The search is done by using - * lower case both text and paramaters. + * Checks if the given text contain the words provided in the condition parameters (case insensitive). * * @param text * string to check @@ -174,35 +192,61 @@ if (text == null) { return false; } + // we parse the condition strings to more useful arrays of words if (!conditionsParsed) { parseConditionStrings(); } - String lowerCaseText = text.toLowerCase(); + + Pattern regexPattern = null; + StringBuilder stringPattern = null; + Matcher matcher = null; + // For each condition type we build a regular expression and try to find it in the text. if (getExcludedWordsCondition() != null) { + stringPattern = new StringBuilder(); for (String excludedWord : getExcludedWordsCondition()) { - if (lowerCaseText.contains(excludedWord)) { - return false; - } + stringPattern.append("(?:").append(TextSearchCondition.WORD_DELIMITER_REGEX).append( + Pattern.quote(excludedWord)).append(TextSearchCondition.WORD_DELIMITER_REGEX).append(")|"); } + stringPattern.deleteCharAt(stringPattern.length() - 1); + regexPattern = Pattern.compile(stringPattern.toString(), TextSearchCondition.PATTERN_MATCHING_OPTIONS); + matcher = regexPattern.matcher(text); + if (matcher.find()) { + return false; + } } if (getAnyWordsCondition() != null) { - boolean wordFound = false; + stringPattern = new StringBuilder(); + for (String word : getAnyWordsCondition()) { - if (lowerCaseText.contains(word)) { - wordFound = true; - break; - } + stringPattern.append("(?:").append(TextSearchCondition.WORD_DELIMITER_REGEX) + .append(Pattern.quote(word)).append(TextSearchCondition.WORD_DELIMITER_REGEX).append(")|"); } - if (!wordFound) { + stringPattern.deleteCharAt(stringPattern.length() - 1); + regexPattern = Pattern.compile(stringPattern.toString(), TextSearchCondition.PATTERN_MATCHING_OPTIONS); + matcher = regexPattern.matcher(text); + if (!matcher.find()) { return false; } } - if (getPhraseCondition() != null && !lowerCaseText.contains(getPhraseCondition())) { - return false; + if (getPhraseCondition() != null) { + stringPattern = new StringBuilder(TextSearchCondition.WORD_DELIMITER_REGEX); + for (String word : getPhraseCondition()) { + stringPattern.append(Pattern.quote(word)).append(TextSearchCondition.WORD_DELIMITER_REGEX); + } + regexPattern = Pattern.compile(stringPattern.toString(), TextSearchCondition.PATTERN_MATCHING_OPTIONS); + matcher = regexPattern.matcher(text); + if (!matcher.find()) { + return false; + } } + if (getAllWordsCondition() != null) { for (String word : getAllWordsCondition()) { - if (!lowerCaseText.contains(word)) { + stringPattern = new StringBuilder(TextSearchCondition.WORD_DELIMITER_REGEX).append(Pattern.quote(word)) + .append(TextSearchCondition.WORD_DELIMITER_REGEX); + regexPattern = Pattern.compile(stringPattern.toString(), TextSearchCondition.PATTERN_MATCHING_OPTIONS); + matcher = regexPattern.matcher(text); + if (!matcher.find()) { return false; } } @@ -227,46 +271,11 @@ */ public void parseConditionStrings(String allWordsString, String phraseString, String anyWordsString, String excludedWordsString) { - conditionsParsed = true; - String trimmed = null; - String[] splited = null; - if (allWordsString != null) { - trimmed = allWordsString.trim(); - splited = trimmed.split(TextSearchCondition.WORD_DELIMITER_REGEX); - for (int index = 0; index < splited.length; index++) { - splited[index] = splited[index].toLowerCase(); - } - - setAllWordsCondition(Arrays.asList(splited)); - } else { - setAllWordsCondition(null); - } - if (phraseString != null) { - trimmed = phraseString.trim(); - setPhraseCondition(trimmed.toLowerCase()); - } - - if (anyWordsString != null) { - trimmed = anyWordsString.trim(); - splited = trimmed.split(TextSearchCondition.WORD_DELIMITER_REGEX); - for (int index = 0; index < splited.length; index++) { - splited[index] = splited[index].toLowerCase(); - } - setAnyWordsCondition(Arrays.asList(splited)); - } else { - setAnyWordsCondition(null); - } - if (excludedWordsString != null) { - trimmed = excludedWordsString.trim(); - splited = trimmed.split(TextSearchCondition.WORD_DELIMITER_REGEX); - for (int index = 0; index < splited.length; index++) { - splited[index] = splited[index].toLowerCase(); - } - setExcludedWordsCondition(Arrays.asList(splited)); - } else { - setExcludedWordsCondition(null); - } + setAllWordsCondition(splitSentence(allWordsString)); + setPhraseCondition(splitSentence(phraseString)); + setAnyWordsCondition(splitSentence(anyWordsString)); + setExcludedWordsCondition(splitSentence(excludedWordsString)); } /** @@ -300,7 +309,7 @@ conditionsParsed = false; } - public void setPhraseCondition(String phraseCondition) { + public void setPhraseCondition(List phraseCondition) { this.phraseCondition = phraseCondition; } @@ -323,4 +332,41 @@ protected void setExcludedWordsCondition(List excludedWordsCondition) { this.excludedWordsCondition = excludedWordsCondition; } + + /** + * Splits the given string into words using configured delimiter. + * + * @param sentence + * string to split + * @return list of non-empty words + */ + private List splitSentence(String sentence) { + List list = null; + if (!StringUtils.isEmpty(sentence)) { + String[] splitted = sentence.trim().split(TextSearchCondition.WORD_DELIMITER_REGEX); + list = new ArrayList(splitted.length); + // we don't need empty words + for (String word : splitted) { + if (!StringUtils.isEmpty(word)) { + list.add(word); + } + } + if (list.isEmpty()) { + list = null; + } + } + return list; + } + + /** + * Strips HTML tags and leave "pure" text. Useful for FCKeditor created text. + * + * @param text + * string to process + * @return string after stripping + */ + public static String removeHTMLtags(String text) { + return text == null ? null : text.replaceAll(TextSearchCondition.BR_TAG_REGEX, " ").replaceAll( + TextSearchCondition.HTML_TAG_REGEX, ""); + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchConditionComparator.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchConditionComparator.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/TextSearchConditionComparator.java (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -0,0 +1,49 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.learningdesign; + +import java.util.Comparator; + + +/** + * Comparator for TextSearchCondition. Only the order ID is compared. + * + * @author Marcin Cieslak + * @see org.lamsfoundation.lams.learningdesign.TextSearchCondition + */ +public class TextSearchConditionComparator implements Comparator { + + /** + * {@inheritDoc} + */ + public int compare(TextSearchCondition o1, TextSearchCondition o2) { + if (o1 != null && o2 != null) { + return o1.getOrderId() - o2.getOrderId(); + } else if (o1 != null) { + return 1; + } else { + return -1; + } + } +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IBranchActivityEntryDAO.java =================================================================== diff -u -r87ec6bd0708e9da634182eacca8c74e442bc748f -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IBranchActivityEntryDAO.java (.../IBranchActivityEntryDAO.java) (revision 87ec6bd0708e9da634182eacca8c74e442bc748f) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IBranchActivityEntryDAO.java (.../IBranchActivityEntryDAO.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -26,18 +26,20 @@ import java.util.List; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; +import org.lamsfoundation.lams.learningdesign.BranchCondition; /** * @author fiona - * + * */ public interface IBranchActivityEntryDAO { - /** - * Returns the list of BranchActivityEntries applicable for the given learning design, determined via the sequence - * activities (which form the related branches) - */ - public abstract List getEntriesByLearningDesign( - Long learningDesignId); + /** + * Returns the list of BranchActivityEntries applicable for the given learning design, determined via the sequence + * activities (which form the related branches) + */ + public abstract List getEntriesByLearningDesign(Long learningDesignId); + BranchCondition getConditionByID(Long conditionID); + } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/BranchActivityEntryDAO.java =================================================================== diff -u -r87ec6bd0708e9da634182eacca8c74e442bc748f -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/BranchActivityEntryDAO.java (.../BranchActivityEntryDAO.java) (revision 87ec6bd0708e9da634182eacca8c74e442bc748f) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/BranchActivityEntryDAO.java (.../BranchActivityEntryDAO.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -27,21 +27,35 @@ import org.lamsfoundation.lams.dao.hibernate.BaseDAO; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; +import org.lamsfoundation.lams.learningdesign.BranchCondition; import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.learningdesign.dao.IBranchActivityEntryDAO; public class BranchActivityEntryDAO extends BaseDAO implements IBranchActivityEntryDAO { - - private final static String ENTRIES_FOR_LEARNING_DESIGN = "select entry from " - + BranchActivityEntry.class.getName() + " entry, " + SequenceActivity.class.getName() + " sequenceActivity " - + " where sequenceActivity.learningDesign.id = ? " - + " and entry.branchSequenceActivity = sequenceActivity"; - /* (non-Javadoc) - * @see org.lamsfoundation.lams.learningdesign.dao.hibernate.IBranchActivityEntryDAO#getEntriesByLearningDesign(java.lang.Long) - */ - public List getEntriesByLearningDesign(Long learningDesignId){ - return (List) this.getHibernateTemplate().find(ENTRIES_FOR_LEARNING_DESIGN,learningDesignId); + private final static String ENTRIES_FOR_LEARNING_DESIGN = "select entry from " + + BranchActivityEntry.class.getName() + " entry, " + SequenceActivity.class.getName() + + " sequenceActivity " + " where sequenceActivity.learningDesign.id = ? " + + " and entry.branchSequenceActivity = sequenceActivity"; + + private final static String CONDITION_BY_ID = "FROM " + BranchCondition.class.getName() + + " con WHERE con.conditionId = ?"; + + /* + * (non-Javadoc) + * + * @see org.lamsfoundation.lams.learningdesign.dao.hibernate.IBranchActivityEntryDAO#getEntriesByLearningDesign(java.lang.Long) + */ + public List getEntriesByLearningDesign(Long learningDesignId) { + return this.getHibernateTemplate().find(BranchActivityEntryDAO.ENTRIES_FOR_LEARNING_DESIGN, learningDesignId); } -} + public BranchCondition getConditionByID(Long conditionID) { + List result = this.getHibernateTemplate().find(BranchActivityEntryDAO.CONDITION_BY_ID, + conditionID); + if (result == null || result.isEmpty()) { + return null; + } + return result.get(0); + } +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsCoreToolService.java =================================================================== diff -u -r7063c259a54239643a9ef50c3bb36ca9f6e7fbb5 -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsCoreToolService.java (.../ILamsCoreToolService.java) (revision 7063c259a54239643a9ef50c3bb36ca9f6e7fbb5) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsCoreToolService.java (.../ILamsCoreToolService.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -23,7 +23,6 @@ /* $$Id$$ */ package org.lamsfoundation.lams.tool.service; - import java.util.List; import java.util.Set; import java.util.SortedMap; @@ -35,317 +34,376 @@ import org.lamsfoundation.lams.tool.ToolOutput; import org.lamsfoundation.lams.tool.ToolOutputDefinition; import org.lamsfoundation.lams.tool.ToolSession; -import org.lamsfoundation.lams.tool.ToolSessionManager; import org.lamsfoundation.lams.tool.exception.DataMissingException; import org.lamsfoundation.lams.tool.exception.LamsToolServiceException; import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.usermanagement.User; import org.springframework.beans.factory.NoSuchBeanDefinitionException; /** - *

This interface defines the service that lams tool package offers to other - * lams core modules, such as, lams_learning, lams_authoring, lams_monitoring.

+ *

+ * This interface defines the service that lams tool package offers to other lams core modules, such as, lams_learning, + * lams_authoring, lams_monitoring. + *

* - *

It doesn't have the tool service that will be called by the tool.

+ *

+ * It doesn't have the tool service that will be called by the tool. + *

* * * @author Jacky Fang - * @since 2005-3-17 + * @since 2005-3-17 * @version 1.1 */ -public interface ILamsCoreToolService -{ +public interface ILamsCoreToolService { /** - * Creates a LAMS ToolSession for a learner and activity. Checks - * to see if an appropriate tool session exists for each learner - * before creating the tool session. + * Creates a LAMS ToolSession for a learner and activity. Checks to see if an appropriate tool session exists for + * each learner before creating the tool session. *

- * If an appropriate tool session already exists for a learner, then - * it returns null. + * If an appropriate tool session already exists for a learner, then it returns null. *

- * Sets up the tool session based on the groupingSupportType. + * Sets up the tool session based on the groupingSupportType. + * * @see org.lamsfoundation.lams.learningdesign.ToolActivity#createToolSessionForActivity(org.lamsfoundation.lams.usermanagement.User,org.lamsfoundation.lams.lesson.Lesson) - * - * @param learner the learner who is running the activity. - * @param activity the requested activity. + * + * @param learner + * the learner who is running the activity. + * @param activity + * the requested activity. * @return toolSession if a new one created, null otherwise. */ - public ToolSession createToolSession(User learner, ToolActivity activity,Lesson lesson) throws LamsToolServiceException; + public ToolSession createToolSession(User learner, ToolActivity activity, Lesson lesson) + throws LamsToolServiceException; /** - * Creates LAMS ToolSessions for a set of learners and activity. Checks - * to see if an appropriate tool session exists for each learner - * before creating the tool session. + * Creates LAMS ToolSessions for a set of learners and activity. Checks to see if an appropriate tool session exists + * for each learner before creating the tool session. *

- * If an appropriate tool session already exists for a learner, then - * it does not include the tool session in the returned set. + * If an appropriate tool session already exists for a learner, then it does not include the tool session in the + * returned set. *

- * @param learners the learners who are running the activity. - * @param activity the requested activity. + * + * @param learners + * the learners who are running the activity. + * @param activity + * the requested activity. * @return toolSessions set of newly created ToolSessions */ - public Set createToolSessions(Set learners, ToolActivity activity,Lesson lesson) throws LamsToolServiceException; + public Set createToolSessions(Set learners, ToolActivity activity, Lesson lesson) throws LamsToolServiceException; /** - * Returns the previously created ToolSession for a learner and activity. - * It is queried base on learner. - * @param learner the learner who owns the tool session. - * @param activity the activity that associate with the tool session. + * Returns the previously created ToolSession for a learner and activity. It is queried base on learner. + * + * @param learner + * the learner who owns the tool session. + * @param activity + * the activity that associate with the tool session. * @return the requested tool session. - * @throws LamsToolServiceException the known error condition when we - * are getting the tool session + * @throws LamsToolServiceException + * the known error condition when we are getting the tool session */ public ToolSession getToolSessionByLearner(User learner, Activity activity) throws LamsToolServiceException; - + /** * Returns the tool session according to tool session id. - * @param toolSessionId the requested tool session id. + * + * @param toolSessionId + * the requested tool session id. * @return the tool session object */ public ToolSession getToolSessionById(Long toolSessionId); - + /** - * Get the lams tool session based on activity. It search through all - * the tool sessions that linked to the requested activity and return - * the tool session with requested learner information. + * Get the lams tool session based on activity. It search through all the tool sessions that linked to the requested + * activity and return the tool session with requested learner information. * - * @param learner the requested learner - * @param toolActivity the requested activity. + * @param learner + * the requested learner + * @param toolActivity + * the requested activity. * @return the tool session. - * @throws LamsToolServiceException the known error condition when we - * are getting the tool session + * @throws LamsToolServiceException + * the known error condition when we are getting the tool session */ - public ToolSession getToolSessionByActivity(User learner, ToolActivity toolActivity)throws LamsToolServiceException; - + public ToolSession getToolSessionByActivity(User learner, ToolActivity toolActivity) + throws LamsToolServiceException; + /** - * Notify tools to create their tool sessions in their own tables. - * @param toolSession the tool session generated by lams. - * @param activity the activity correspondent to that tool session. + * Notify tools to create their tool sessions in their own tables. + * + * @param toolSession + * the tool session generated by lams. + * @param activity + * the activity correspondent to that tool session. */ - public void notifyToolsToCreateSession(ToolSession toolSession, ToolActivity activity) - throws ToolException; - + public void notifyToolsToCreateSession(ToolSession toolSession, ToolActivity activity) throws ToolException; + /** - * Calls the tool to copy the content for an activity. Used when copying a learning design. - * If it is a preview lesson, we don't want to set define later - we will sidestep this in the progress engine. + * Calls the tool to copy the content for an activity. Used when copying a learning design. If it is a preview + * lesson, we don't want to set define later - we will sidestep this in the progress engine. * - * @param toolActivity the tool activity defined in the design. - * @param setDefineLater whether or not to set the define later flag. - * @param customCSV custom comma-separated values used for tool adapters - * @throws DataMissingException, ToolException + * @param toolActivity + * the tool activity defined in the design. + * @param setDefineLater + * whether or not to set the define later flag. + * @param customCSV + * custom comma-separated values used for tool adapters + * @throws DataMissingException, + * ToolException * @see org.lamsfoundation.lams.tool.service.ILamsCoreToolService#notifyToolToCopyContent(org.lamsfoundation.lams.learningdesign.ToolActivity) */ - public Long notifyToolToCopyContent(ToolActivity toolActivity, boolean setDefineLater, String customCSV) - throws DataMissingException, ToolException; - + public Long notifyToolToCopyContent(ToolActivity toolActivity, boolean setDefineLater, String customCSV) + throws DataMissingException, ToolException; + /** * Calls the tool to set up the define later and run offline flags. * - * This method is a subset of the functionality of notifyToolToCopyContent(ToolActivity toolActivity, boolean setDefineLater); - * so if you call notifyToolToCopyContent then you don't need to call this method. It is a separate method used by Live Edit. + * This method is a subset of the functionality of notifyToolToCopyContent(ToolActivity toolActivity, boolean + * setDefineLater); so if you call notifyToolToCopyContent then you don't need to call this method. It is a separate + * method used by Live Edit. * - * @param toolActivity the tool activity defined in the design. - * @throws DataMissingException, ToolException + * @param toolActivity + * the tool activity defined in the design. + * @throws DataMissingException, + * ToolException * @see org.lamsfoundation.lams.tool.service.ILamsCoreToolService#notifyToolToCopyContent(org.lamsfoundation.lams.learningdesign.ToolActivity) */ - public Long notifyToolOfStatusFlags(ToolActivity toolActivity) - throws DataMissingException, ToolException; + public Long notifyToolOfStatusFlags(ToolActivity toolActivity) throws DataMissingException, ToolException; /** - * Calls the tool to copy the content for an activity. Used when copying an activity in authoring. Can't - * use the notifyToolToCopyContent(ToolActivity, boolean) version in authoring as the tool activity won't - * exist if the user hasn't saved the sequence yet. But the tool content (as that is saved by the - * tool) may already exist. + * Calls the tool to copy the content for an activity. Used when copying an activity in authoring. Can't use the + * notifyToolToCopyContent(ToolActivity, boolean) version in authoring as the tool activity won't exist if the user + * hasn't saved the sequence yet. But the tool content (as that is saved by the tool) may already exist. * - * This doesn't set the define later and run offline flags from the design - it only copies the content - * stored in the tool. + * This doesn't set the define later and run offline flags from the design - it only copies the content stored in + * the tool. * - * @param toolContentId the content to be copied. - * @param customCSV the customCSV required if this is a tooladapter tool, otherwise null - * @throws DataMissingException, ToolException + * @param toolContentId + * the content to be copied. + * @param customCSV + * the customCSV required if this is a tooladapter tool, otherwise null + * @throws DataMissingException, + * ToolException * @see org.lamsfoundation.lams.tool.service.ILamsCoreToolService#notifyToolToCopyContent(org.lamsfoundation.lams.learningdesign.ToolActivity) */ - public Long notifyToolToCopyContent(Long toolContentId, String customCSV) - throws DataMissingException, ToolException; + public Long notifyToolToCopyContent(Long toolContentId, String customCSV) throws DataMissingException, + ToolException; + /** - * Ask a tool to delete a tool content. If any related tool session data exists then it should - * be deleted. + * Ask a tool to delete a tool content. If any related tool session data exists then it should be deleted. * - * @param toolActivity the tool activity defined in the design. - * @throws ToolException + * @param toolActivity + * the tool activity defined in the design. + * @throws ToolException */ public void notifyToolToDeleteContent(ToolActivity toolActivity) throws ToolException; /** - * Ask a tool for its OutputDefinitions, based on the given toolContentId. If the tool doesn't - * have any content matching the toolContentId then it should create the OutputDefinitions based - * on the tool's default content. + * Ask a tool for its OutputDefinitions, based on the given toolContentId. If the tool doesn't have any content + * matching the toolContentId then it should create the OutputDefinitions based on the tool's default content. * - * This functionality relies on a method added to the Tool Contract in LAMS 2.1, so if the tool - * doesn't support the required method, it writes out an error to the log but doesn't throw - * an exception - just returns an empty map. - * + * This functionality relies on a method added to the Tool Contract in LAMS 2.1, so if the tool doesn't support the + * required method, it writes out an error to the log but doesn't throw an exception - just returns an empty map. + * * @param toolContentId * @return SortedMap of ToolOutputDefinitions with the key being the name of each definition - * @throws ToolException + * @throws ToolException */ - public SortedMap getOutputDefinitionsFromTool(Long toolContentId) throws ToolException; - + public SortedMap getOutputDefinitionsFromTool(Long toolContentId) + throws ToolException; + /** - * Ask a tool for one particular ToolOutput, based on the given toolSessionId. If the tool doesn't - * have any content matching the toolSessionId then should return an "empty" but valid set of data. e.g - * an empty mark would be 0. + * Ask a tool for one particular ToolOutput, based on the given toolSessionId. If the tool doesn't have any content + * matching the toolSessionId then should return an "empty" but valid set of data. e.g an empty mark would be 0. * * This functionality relies on a method added to the Tool Contract in LAMS 2.1. * - * @throws ToolException + * @throws ToolException */ - public ToolOutput getOutputFromTool(String conditionName, Long toolSessionId, Integer learnerId) throws ToolException; - + public ToolOutput getOutputFromTool(String conditionName, Long toolSessionId, Integer learnerId) + throws ToolException; + /** - * Ask a tool for one particular ToolOutput, based on the given toolSessionId. If the tool doesn't - * have any content matching the toolSessionId then should return an "empty" but valid set of data. e.g - * an empty mark would be 0. + * Ask a tool for one particular ToolOutput, based on the given toolSessionId. If the tool doesn't have any content + * matching the toolSessionId then should return an "empty" but valid set of data. e.g an empty mark would be 0. * * This functionality relies on a method added to the Tool Contract in LAMS 2.1. * - * @throws ToolException + * @throws ToolException */ - public ToolOutput getOutputFromTool(String conditionName, ToolSession toolSession, Integer learnerId) throws ToolException; - + public ToolOutput getOutputFromTool(String conditionName, ToolSession toolSession, Integer learnerId) + throws ToolException; + /** - * Ask a tool for a set of ToolOutputs, based on the given toolSessionId. + * Ask a tool for a set of ToolOutputs, based on the given toolSessionId. * - * If conditionName array is null, then return all the outputs for the tool, otherwise just restrict the - * outputs to the given list. If it is empty, then no outputs will be returned. + * If conditionName array is null, then return all the outputs for the tool, otherwise just restrict the outputs to + * the given list. If it is empty, then no outputs will be returned. * - * If the learnerId is null, then return the outputs based on all learners in that toolSession. If the - * output is nonsense for all learners, then return an "empty" but valid answer. For example, for a mark - * you might return 0. + * If the learnerId is null, then return the outputs based on all learners in that toolSession. If the output is + * nonsense for all learners, then return an "empty" but valid answer. For example, for a mark you might return 0. * - * If there isn't any content matching the toolSessionId then should return an "empty" but valid set of data. e.g - * an empty mark would be 0. + * If there isn't any content matching the toolSessionId then should return an "empty" but valid set of data. e.g an + * empty mark would be 0. * * This functionality relies on a method added to the Tool Contract in LAMS 2.1. * - * @throws ToolException + * @throws ToolException */ - public SortedMap getOutputFromTool(List names, Long toolSessionId, Integer learnerId) throws ToolException; - + public SortedMap getOutputFromTool(List names, Long toolSessionId, Integer learnerId) + throws ToolException; + /** - * Ask a tool for a set of ToolOutputs, based on the given toolSessionId. + * Ask a tool for a set of ToolOutputs, based on the given toolSessionId. * - * If conditionName array is null, then return all the outputs for the tool, otherwise just restrict the - * outputs to the given list. If it is empty, then no outputs will be returned. + * If conditionName array is null, then return all the outputs for the tool, otherwise just restrict the outputs to + * the given list. If it is empty, then no outputs will be returned. * - * If the learnerId is null, then return the outputs based on all learners in that toolSession. If the - * output is nonsense for all learners, then return an "empty" but valid answer. For example, for a mark - * you might return 0. + * If the learnerId is null, then return the outputs based on all learners in that toolSession. If the output is + * nonsense for all learners, then return an "empty" but valid answer. For example, for a mark you might return 0. * - * If there isn't any content matching the toolSessionId then should return an "empty" but valid set of data. e.g - * an empty mark would be 0. + * If there isn't any content matching the toolSessionId then should return an "empty" but valid set of data. e.g an + * empty mark would be 0. * * This functionality relies on a method added to the Tool Contract in LAMS 2.1. * - * @throws ToolException + * @throws ToolException */ - public SortedMap getOutputFromTool(List names, ToolSession toolSession, Integer learnerId) throws ToolException; + public SortedMap getOutputFromTool(List names, ToolSession toolSession, + Integer learnerId) throws ToolException; /** * Update the tool session data. - * @param toolSession the new tool session object. + * + * @param toolSession + * the new tool session object. */ public void updateToolSession(ToolSession toolSession); /** * Return tool activity url for a learner. See also getToolPreviewURL, getToolLearnerProgressURL - * @param lesson id - needed for the SystemToolActivities - * @param activity the requested activity - should be either a ToolActivity or a SystemToolActivity - * @param learner the current learner. + * + * @param lesson + * id - needed for the SystemToolActivities + * @param activity + * the requested activity - should be either a ToolActivity or a SystemToolActivity + * @param learner + * the current learner. * @return the tool access url with tool session id or activity id */ public String getToolLearnerURL(Long lessonID, Activity activity, User learner) throws LamsToolServiceException; /** - * Return tool activity url for running a tool in preview mode. See also getToolLearnerURL, getToolLearnerProgressURL - * @param lesson id - needed for the SystemToolActivities - * @param activity the requested activity - should be either a ToolActivity or a SystemToolActivity - * @param learner the current learner. + * Return tool activity url for running a tool in preview mode. See also getToolLearnerURL, + * getToolLearnerProgressURL + * + * @param lesson + * id - needed for the SystemToolActivities + * @param activity + * the requested activity - should be either a ToolActivity or a SystemToolActivity + * @param learner + * the current learner. * @return the tool access url with tool session id or activity id */ - public String getToolLearnerPreviewURL(Long lessonID, Activity activity, User learner) throws LamsToolServiceException; + public String getToolLearnerPreviewURL(Long lessonID, Activity activity, User learner) + throws LamsToolServiceException; /** * Return tool activity url for running a tool in preview mode. See also getToolLearnerURL, getToolPreviewURL - * @param lesson id - needed for the SystemToolActivities - * @param activity the requested activity - should be either a ToolActivity or a SystemToolActivity - * @param learner the current learner. + * + * @param lesson + * id - needed for the SystemToolActivities + * @param activity + * the requested activity - should be either a ToolActivity or a SystemToolActivity + * @param learner + * the current learner. * @return the tool access url with tool session id or activity id */ - public String getToolLearnerProgressURL(Long lessonID, Activity activity, User learner) throws LamsToolServiceException; + public String getToolLearnerProgressURL(Long lessonID, Activity activity, User learner) + throws LamsToolServiceException; /** - * Return tool activity url for monitoring. - * @param lesson id - needed for the SystemToolActivities - * @param activity the requested activity - should be either a ToolActivity or a SystemToolActivity + * Return tool activity url for monitoring. + * + * @param lesson + * id - needed for the SystemToolActivities + * @param activity + * the requested activity - should be either a ToolActivity or a SystemToolActivity * @return the tool access url with tool session id or activity id */ public String getToolMonitoringURL(Long lessonID, Activity activity) throws LamsToolServiceException; /** * Return the contribution url for monitoring. - * @param lesson id - needed for the SystemToolActivities - * @param activity the requested activity - should be either a ToolActivity or a SystemToolActivity + * + * @param lesson + * id - needed for the SystemToolActivities + * @param activity + * the requested activity - should be either a ToolActivity or a SystemToolActivity * @return the tool access url with tool session id or activity id */ public String getToolContributionURL(Long lessonID, Activity activity) throws LamsToolServiceException; /** - * Return the define later url for monitoring. - * @param activity the requested activity - must be a a ToolActivity. System Activities don't support define later. + * Return the define later url for monitoring. + * + * @param activity + * the requested activity - must be a a ToolActivity. System Activities don't support define later. * @return the tool access url with tool content id */ public String getToolDefineLaterURL(ToolActivity activity) throws LamsToolServiceException; /** - * Return the moderate url for monitoring. - * @param activity the requested activity - must be a a ToolActivity. System Activities don't support moderation. + * Return the moderate url for monitoring. + * + * @param activity + * the requested activity - must be a a ToolActivity. System Activities don't support moderation. * @return the tool access url with tool content id */ public String getToolModerateURL(ToolActivity activity) throws LamsToolServiceException; /** * Get all the tool sessions for a lesson. The resulting list is not sorted. - * @return list of ToolSession objects + * + * @return list of ToolSession objects */ public List getToolSessionsByLesson(Lesson lesson); - - + /** - * Delete a tool session. Calls the tool to delete its session details and then - * deletes the main tool session record. If the tool throws an exception, the main - * tool session record is still deleted. + * Delete a tool session. Calls the tool to delete its session details and then deletes the main tool session + * record. If the tool throws an exception, the main tool session record is still deleted. */ public void deleteToolSession(ToolSession toolSession); /** - *

Setup target tool url with tool session id parameter based on the tool - * activity and learner.

+ *

+ * Setup target tool url with tool session id parameter based on the tool activity and learner. + *

* - * @param activity the activity that requested tool session belongs to. - * @param learner the user who invloved the tool session. - * @param toolURL the target url. + * @param activity + * the activity that requested tool session belongs to. + * @param learner + * the user who invloved the tool session. + * @param toolURL + * the target url. * @throws LamsToolServiceException * @return the url with tool session id. */ - public String setupToolURLWithToolSession(ToolActivity activity,User learner,String toolURL) throws LamsToolServiceException; - + public String setupToolURLWithToolSession(ToolActivity activity, User learner, String toolURL) + throws LamsToolServiceException; + /** - *

Setup target tool url with tool content id parameter based on the tool - * activity and learner.

- * @param activity the requested activity. - * @param toolURL the target url + *

+ * Setup target tool url with tool content id parameter based on the tool activity and learner. + *

+ * + * @param activity + * the requested activity. + * @param toolURL + * the target url * @return the url with tool content id. */ - public String setupToolURLWithToolContent(ToolActivity activity,String toolURL); + public String setupToolURLWithToolContent(ToolActivity activity, String toolURL); + + public Object findToolService(Tool tool) throws NoSuchBeanDefinitionException; } Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java =================================================================== diff -u -r1acf9b895293f09b11caf05e6f76d939be4010af -r542b83631b403e37429fce3bb928f2800c5cd9b8 --- lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java (.../LamsCoreToolService.java) (revision 1acf9b895293f09b11caf05e6f76d939be4010af) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java (.../LamsCoreToolService.java) (revision 542b83631b403e37429fce3bb928f2800c5cd9b8) @@ -779,7 +779,7 @@ * @throws NoSuchBeanDefinitionException * if the tool is not the classpath or the supplied service name is wrong. */ - private Object findToolService(Tool tool) throws NoSuchBeanDefinitionException { + public Object findToolService(Tool tool) throws NoSuchBeanDefinitionException { return context.getBean(tool.getServiceName()); }