Index: lams_build/lib/lams/lams.jar =================================================================== RCS file: /usr/local/cvsroot/lams_build/lib/lams/lams.jar,v diff -u -r1.391 -r1.392 Binary files differ Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java,v diff -u -r1.86 -r1.87 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java 29 Nov 2013 13:32:52 -0000 1.86 +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java 3 Dec 2013 20:30:00 -0000 1.87 @@ -94,6 +94,8 @@ import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; import org.lamsfoundation.lams.util.DateUtil; +import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.wddx.WDDXProcessor; import org.lamsfoundation.lams.util.wddx.WDDXProcessorConversionException; import org.lamsfoundation.lams.util.wddx.WDDXTAGS; @@ -503,7 +505,7 @@ // Check the copy type. Can only update it if it is COPY_TYPE_NONE (ie // authoring copy) - Integer copyTypeID = ldJSON.optInt(AuthoringJsonTags.COPY_TYPE); + Integer copyTypeID = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.COPY_TYPE); if (copyTypeID == null) { copyTypeID = LearningDesign.COPY_TYPE_NONE; } @@ -519,9 +521,15 @@ learningDesign.setWorkspaceFolder(workspaceFolder); learningDesign.setUser(user); + String contentFolderID = (String) JsonUtil.opt(ldJSON, AuthoringJsonTags.CONTENT_FOLDER_ID); + if (contentFolderID == null) { + contentFolderID = FileUtil.generateUniqueContentFolderID(); + ldJSON.put(AuthoringJsonTags.CONTENT_FOLDER_ID, contentFolderID); + } + learningDesign.setContentFolderID(contentFolderID); if (existingLearningDesign == null) { - Integer originalUserID = ldJSON.optInt(AuthoringJsonTags.ORIGINAL_USER_ID); + Integer originalUserID = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.ORIGINAL_USER_ID); if (originalUserID == null) { learningDesign.setOriginalUser(user); } else { @@ -549,24 +557,24 @@ initialiseToolSessionMap(learningDesign); // get the core learning design stuff - default to invalid - learningDesign.setValidDesign(ldJSON.optBoolean(AuthoringJsonTags.VALID_DESIGN, false)); - learningDesign.setLearningDesignUIID(ldJSON.optInt(AuthoringJsonTags.LEARNING_DESIGN_UIID)); - learningDesign.setDescription(ldJSON.optString(AuthoringJsonTags.DESCRIPTION)); - learningDesign.setTitle(ldJSON.optString(AuthoringJsonTags.TITLE)); - learningDesign.setMaxID(ldJSON.optInt(AuthoringJsonTags.MAX_ID)); - learningDesign.setReadOnly(ldJSON.optBoolean(AuthoringJsonTags.READ_ONLY)); - learningDesign.setEditOverrideLock(ldJSON.optBoolean(AuthoringJsonTags.EDIT_OVERRIDE_LOCK)); - learningDesign.setDateReadOnly(DateUtil.convertFromString(ldJSON.optString(AuthoringJsonTags.DATE_READ_ONLY))); - learningDesign.setHelpText(ldJSON.optString(AuthoringJsonTags.HELP_TEXT)); - String version = ldJSON.optString(AuthoringJsonTags.VERSION); + learningDesign.setValidDesign(JsonUtil.opt(ldJSON, AuthoringJsonTags.VALID_DESIGN, false)); + learningDesign.setLearningDesignUIID((Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.LEARNING_DESIGN_UIID)); + learningDesign.setDescription((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.DESCRIPTION)); + learningDesign.setTitle((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.TITLE)); + learningDesign.setMaxID((Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.MAX_ID)); + learningDesign.setReadOnly((Boolean) JsonUtil.opt(ldJSON, AuthoringJsonTags.READ_ONLY)); + learningDesign.setEditOverrideLock((Boolean) JsonUtil.opt(ldJSON, AuthoringJsonTags.EDIT_OVERRIDE_LOCK)); + learningDesign.setDateReadOnly(DateUtil.convertFromString((String) JsonUtil.opt(ldJSON, + AuthoringJsonTags.DATE_READ_ONLY))); + learningDesign.setHelpText((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.HELP_TEXT)); + String version = (String) JsonUtil.opt(ldJSON, AuthoringJsonTags.VERSION); if (version == null) { version = Configuration.get(ConfigurationKeys.SERVER_VERSION_NUMBER); } learningDesign.setVersion(version); - learningDesign.setDuration(ldJSON.optLong(AuthoringJsonTags.DURATION)); - learningDesign.setContentFolderID(ldJSON.optString(AuthoringJsonTags.CONTENT_FOLDER_ID)); + learningDesign.setDuration(JsonUtil.optLong(ldJSON, AuthoringJsonTags.DURATION)); - mode = ldJSON.optInt(AuthoringJsonTags.SAVE_MODE); + mode = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.SAVE_MODE); // Set creation date and modification date based on the server timezone, // not the client. @@ -575,14 +583,14 @@ } learningDesign.setLastModifiedDateTime(modificationDate); - Long licenseID = ldJSON.optLong(AuthoringJsonTags.LICENCE_ID); + Long licenseID = JsonUtil.optLong(ldJSON, AuthoringJsonTags.LICENCE_ID); if (licenseID != null) { License license = licenseDAO.getLicenseByID(licenseID); learningDesign.setLicense(license); } - learningDesign.setLicenseText(ldJSON.optString(AuthoringJsonTags.LICENSE_TEXT)); + learningDesign.setLicenseText((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.LICENSE_TEXT)); - Long originalLearningDesignID = ldJSON.optLong(AuthoringJsonTags.ORIGINAL_DESIGN_ID); + Long originalLearningDesignID = JsonUtil.optLong(ldJSON, AuthoringJsonTags.ORIGINAL_DESIGN_ID); if (originalLearningDesignID != null) { LearningDesign originalLearningDesign = learningDesignDAO.getLearningDesignById(originalLearningDesignID); learningDesign.setOriginalLearningDesign(originalLearningDesign); @@ -591,12 +599,11 @@ learningDesignDAO.insertOrUpdate(learningDesign); // now process the "parts" of the learning design - parseCompetences(ldJSON.optJSONArray(AuthoringJsonTags.COMPETENCES)); - parseGroupings(ldJSON.optJSONArray(AuthoringJsonTags.GROUPINGS)); - parseActivities(ldJSON.optJSONArray(AuthoringJsonTags.ACTIVITIES)); - parseActivitiesToMatchUpParentandInputActivities(ldJSON.optJSONArray(AuthoringJsonTags.ACTIVITIES)); - parseTransitions(ldJSON.optJSONArray(AuthoringJsonTags.TRANSITIONS)); - parseBranchMappings(ldJSON.optJSONArray(AuthoringJsonTags.BRANCH_MAPPINGS)); + parseGroupings((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.GROUPINGS)); + parseActivities((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.ACTIVITIES)); + parseActivitiesToMatchUpParentandInputActivities((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.ACTIVITIES)); + parseTransitions((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.TRANSITIONS)); + parseBranchMappings((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.BRANCH_MAPPINGS)); progressDefaultChildActivities(); @@ -606,7 +613,6 @@ deleteUnwantedGroupings(); deleteUnwantedToolSessions(learningDesign); - parseCompetenceMappings(ldJSON.optJSONArray(AuthoringJsonTags.ACTIVITIES)); learningDesignDAO.insertOrUpdate(learningDesign); return learningDesign; } @@ -887,8 +893,8 @@ } public Grouping extractGroupingObject(JSONObject groupingDetails) throws JSONException { - Integer groupingUIID = groupingDetails.optInt("groupingUIID"); - Integer groupingTypeID = groupingDetails.getInt("groupingTypeID"); + Integer groupingUIID = (Integer) JsonUtil.opt(groupingDetails, "groupingUIID"); + Integer groupingTypeID = (Integer) JsonUtil.opt(groupingDetails, "groupingTypeID"); Grouping grouping = groupings.get(groupingUIID); // check that the grouping type is still okay - if it is we keep the @@ -921,11 +927,11 @@ createLessonClass((LessonClass) grouping, groupingDetails); } - grouping.setMaxNumberOfGroups(groupingDetails.optInt("maxNumberOfGroups")); + grouping.setMaxNumberOfGroups((Integer) JsonUtil.opt(groupingDetails, "maxNumberOfGroups")); Set groupsToDelete = new HashSet(grouping.getGroups()); - JSONArray groupsList = groupingDetails.optJSONArray("groups"); + JSONArray groupsList = (JSONArray) JsonUtil.opt(groupingDetails, "groups"); if (groupsList != null) { for (int groupIndex = 0; groupIndex < groupsList.length(); groupIndex++) { JSONObject groupDetails = groupsList.getJSONObject(groupIndex); @@ -1010,7 +1016,7 @@ Group group = null; Integer groupUIID = groupDetails.getInt(AuthoringJsonTags.GROUP_UIID); - Long groupID = groupDetails.optLong(AuthoringJsonTags.GROUP_ID); + Long groupID = JsonUtil.optLong(groupDetails, AuthoringJsonTags.GROUP_ID); // Does it exist already? If the group was created at runtime, there // will be an ID but no IU ID field. @@ -1041,10 +1047,10 @@ grouping.getGroups().add(group); } - group.setGroupName(groupDetails.optString(AuthoringJsonTags.GROUP_NAME)); + group.setGroupName((String) JsonUtil.opt(groupDetails, AuthoringJsonTags.GROUP_NAME)); group.setGrouping(grouping); group.setGroupUIID(groupUIID); - group.setOrderId(groupDetails.optInt(AuthoringJsonTags.ORDER_ID, 0)); + group.setOrderId(JsonUtil.opt(groupDetails, AuthoringJsonTags.ORDER_ID, 0)); return group; } @@ -1068,15 +1074,15 @@ } } - private void createRandomGrouping(RandomGrouping randomGrouping, JSONObject groupingDetails) { + private void createRandomGrouping(RandomGrouping randomGrouping, JSONObject groupingDetails) throws JSONException { // the two settings are mutually exclusive. Flash takes care of this, // but we'll code it here too just to make sure. - Integer numLearnersPerGroup = groupingDetails.optInt(AuthoringJsonTags.LEARNERS_PER_GROUP); + Integer numLearnersPerGroup = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); if ((numLearnersPerGroup != null) && (numLearnersPerGroup.intValue() > 0)) { randomGrouping.setLearnersPerGroup(numLearnersPerGroup); randomGrouping.setNumberOfGroups(null); } else { - Integer numGroups = groupingDetails.optInt(AuthoringJsonTags.NUMBER_OF_GROUPS); + Integer numGroups = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); if ((numGroups != null) && (numGroups.intValue() > 0)) { randomGrouping.setNumberOfGroups(numGroups); } else { @@ -1223,7 +1229,7 @@ } private void extractEvaluationObject(JSONObject activityDetails, ToolActivity toolActivity) - throws ObjectExtractorException { + throws ObjectExtractorException, JSONException { Set activityEvaluations = toolActivity.getActivityEvaluations(); ActivityEvaluation activityEvaluation; @@ -1235,7 +1241,7 @@ activityEvaluation = new ActivityEvaluation(); } - String toolOutputDefinition = activityDetails.optString(AuthoringJsonTags.TOOL_OUTPUT_DEFINITION); + String toolOutputDefinition = (String) JsonUtil.opt(activityDetails, AuthoringJsonTags.TOOL_OUTPUT_DEFINITION); if (!StringUtils.isBlank(toolOutputDefinition)) { activityEvaluations = new HashSet(); activityEvaluation.setActivity(toolActivity); @@ -1364,104 +1370,6 @@ } } - private void parseCompetenceMappings(JSONArray activitiesList) throws ObjectExtractorException, JSONException { - - if (activitiesList != null) { - for (int activityIndex = 0; activityIndex < activitiesList.length(); activityIndex++) { - JSONObject activityDetails = activitiesList.getJSONObject(activityIndex); - // Check that this is a tool activity, otherwise continue to the - // next iteration - Integer actType = activityDetails.optInt(AuthoringJsonTags.ACTIVITY_TYPE_ID); - if ((actType == null) || (actType != Activity.TOOL_ACTIVITY_TYPE)) { - continue; - } - - // Get the tool activity using the UIID and the learningDesignID - ToolActivity toolActivity = null; - Integer activityUIID = activityDetails.optInt(AuthoringJsonTags.ACTIVITY_UIID); - if (activityUIID == null) { - continue; - } else { - Activity activity = activityDAO.getActivityByUIID(activityUIID, learningDesign); - toolActivity = (ToolActivity) activity; - } - - JSONArray competenceMappingsList = activityDetails.optJSONArray(AuthoringJsonTags.COMPETENCE_MAPPINGS); - - if (competenceMappingsList != null) { - for (int competenceMappingIndex = 0; competenceMappingIndex < competenceMappingsList.length(); competenceMappingIndex++) { - String competenceMappingEntry = competenceMappingsList.getString(competenceMappingIndex); - - if (toolActivity.getActivityId() != null) { - - // First get the competence from the competence - // mapping entry in the hashtable - Competence competence = competenceDAO.getCompetence(toolActivity.getLearningDesign(), - competenceMappingEntry); - if (competence == null) { - continue; - } - - // Now get the competence mapping using the tool - // activity and the competence as reference - CompetenceMapping competenceMapping = competenceMappingDAO.getCompetenceMapping( - toolActivity, competence); - - // Only save new competence mappings, no need to - // update existing - if (competenceMapping == null) { - CompetenceMapping newMapping = new CompetenceMapping(); - newMapping.setCompetence(competence); - newMapping.setToolActivity(toolActivity); - - // 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); - } - } - } - - // delete any pre-existing mappings that have been deleted - Set existingMappings = toolActivity.getCompetenceMappings(); - if (existingMappings != null) { - Set removeCompetenceMappings = new HashSet(); - - if ((competenceMappingsList != null) && (competenceMappingsList.length() > 0)) { - for (CompetenceMapping competenceMapping : existingMappings) { - boolean remove = true; - - for (int competenceMappingIndex = 0; competenceMappingIndex < competenceMappingsList - .length(); competenceMappingIndex++) { - String competenceMappingEntry = competenceMappingsList - .getString(competenceMappingIndex); - if (competenceMappingEntry.equals(competenceMapping.getCompetence().getTitle())) { - remove = false; - break; - } - } - - if (remove) { - removeCompetenceMappings.add(competenceMapping); - } - } - } else { - removeCompetenceMappings.addAll(existingMappings); - } - competenceMappingDAO.deleteAll(removeCompetenceMappings); - toolActivity.getCompetenceMappings().removeAll(removeCompetenceMappings); - } - } - } - } - /** * 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, @@ -1664,7 +1572,7 @@ Activity existingActivity = newActivityMap.get(activityUUID); // match up activity to parent based on UIID - Integer parentUIID = activityDetails.optInt(AuthoringJsonTags.PARENT_UIID); + Integer parentUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.PARENT_UIID); if (parentUIID != null) { Activity parentActivity = newActivityMap.get(parentUIID); @@ -1690,7 +1598,8 @@ // match up activity to input activities based on UIID. At // present there will be only one input activity existingActivity.getInputActivities().clear(); - Integer inputActivityUIID = activityDetails.optInt(AuthoringJsonTags.INPUT_TOOL_ACTIVITY_UIID); + Integer inputActivityUIID = (Integer) JsonUtil.opt(activityDetails, + AuthoringJsonTags.INPUT_TOOL_ACTIVITY_UIID); if (inputActivityUIID != null) { Activity inputActivity = newActivityMap.get(inputActivityUIID); if (inputActivity == null) { @@ -1804,8 +1713,8 @@ public Activity extractActivityObject(JSONObject activityDetails) throws ObjectExtractorException, JSONException { // it is assumed that the activityUUID will always be sent by flash. - Integer activityUIID = activityDetails.optInt(AuthoringJsonTags.ACTIVITY_UIID); - Integer activityTypeID = activityDetails.getInt(AuthoringJsonTags.ACTIVITY_TYPE_ID); + Integer activityUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_UIID); + Integer activityTypeID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_TYPE_ID); Activity activity = null; // get the activity with the particular activity uuid, if null, then new @@ -1824,14 +1733,18 @@ activity.setActivityTypeId(activityTypeID); activity.setActivityUIID(activityUIID); - activity.setDescription(activityDetails.optString(AuthoringJsonTags.DESCRIPTION)); - activity.setTitle(activityDetails.optString(AuthoringJsonTags.ACTIVITY_TITLE)); - activity.setHelpText(activityDetails.optString(AuthoringJsonTags.HELP_TEXT)); + activity.setDescription((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.DESCRIPTION)); + activity.setTitle((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_TITLE)); + activity.setHelpText((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.HELP_TEXT)); + + // to be removed soon + activity.setDefineLater(false); + activity.setRunOffline(false); activity.setXcoord(getCoord(activityDetails, AuthoringJsonTags.XCOORD)); activity.setYcoord(getCoord(activityDetails, AuthoringJsonTags.YCOORD)); - Integer groupingUIID = activityDetails.optInt(AuthoringJsonTags.GROUPING_UIID); + Integer groupingUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.GROUPING_UIID); if (groupingUIID == null) { clearGrouping(activity); @@ -1847,12 +1760,11 @@ } - activity.setOrderId(activityDetails.optInt(AuthoringJsonTags.ORDER_ID)); - activity.setDefineLater(activityDetails.optBoolean(AuthoringJsonTags.DEFINE_LATER)); + activity.setOrderId((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ORDER_ID)); activity.setLearningDesign(learningDesign); - Long learningLibraryID = activityDetails.optLong(AuthoringJsonTags.LEARNING_LIBRARY_ID); + Long learningLibraryID = JsonUtil.optLong(activityDetails, AuthoringJsonTags.LEARNING_LIBRARY_ID); if (learningLibraryID != null) { LearningLibrary library = learningLibraryDAO.getLearningLibraryById(learningLibraryID); @@ -1864,11 +1776,11 @@ activity.setCreateDateTime(modificationDate); } - activity.setRunOffline(activityDetails.optBoolean(AuthoringJsonTags.RUN_OFFLINE)); - activity.setActivityCategoryID(activityDetails.optInt(AuthoringJsonTags.ACTIVITY_CATEGORY_ID)); - activity.setLibraryActivityUiImage(activityDetails.optString(AuthoringJsonTags.LIBRARY_IMAGE)); - activity.setGroupingSupportType(activityDetails.optInt(AuthoringJsonTags.GROUPING_SUPPORT_TYPE)); - activity.setStopAfterActivity(activityDetails.optBoolean(AuthoringJsonTags.STOP_AFTER_ACTIVITY)); + activity.setActivityCategoryID((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_CATEGORY_ID)); + activity.setLibraryActivityUiImage((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.LIBRARY_IMAGE)); + activity.setGroupingSupportType((Integer) JsonUtil + .opt(activityDetails, AuthoringJsonTags.GROUPING_SUPPORT_TYPE)); + activity.setStopAfterActivity((Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.STOP_AFTER_ACTIVITY)); return activity; } @@ -1990,8 +1902,8 @@ return (coord == null) || (coord >= 0) ? coord : ObjectExtractor.DEFAULT_COORD; } - private Integer getCoord(JSONObject details, String tag) { - Integer coord = details.optInt(tag); + private Integer getCoord(JSONObject details, String tag) throws JSONException { + Integer coord = (Integer) JsonUtil.opt(details, tag); return (coord == null) || (coord >= 0) ? coord : ObjectExtractor.DEFAULT_COORD; } @@ -2062,15 +1974,16 @@ } private void buildComplexActivity(ComplexActivity activity, JSONObject activityDetails) - throws ObjectExtractorException { + throws ObjectExtractorException, JSONException { // 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.setDefaultActivity(null); - Integer defaultActivityMapUIID = activityDetails.optInt(AuthoringJsonTags.DEFAULT_ACTIVITY_UIID); + Integer defaultActivityMapUIID = (Integer) JsonUtil.opt(activityDetails, + AuthoringJsonTags.DEFAULT_ACTIVITY_UIID); if (defaultActivityMapUIID != null) { defaultActivityMap.put(defaultActivityMapUIID, activity); } @@ -2100,8 +2013,9 @@ } private void buildFloatingActivity(FloatingActivity floatingActivity, JSONObject activityDetails) - throws ObjectExtractorException { - floatingActivity.setMaxNumberOfActivities(activityDetails.optInt(AuthoringJsonTags.MAX_ACTIVITIES)); + throws ObjectExtractorException, JSONException { + floatingActivity.setMaxNumberOfActivities((Integer) JsonUtil.opt(activityDetails, + AuthoringJsonTags.MAX_ACTIVITIES)); SystemTool systemTool = getSystemTool(SystemTool.FLOATING_ACTIVITIES); floatingActivity.setSystemTool(systemTool); @@ -2124,7 +2038,7 @@ } private void buildBranchingActivity(BranchingActivity branchingActivity, JSONObject activityDetails) - throws ObjectExtractorException { + throws ObjectExtractorException, JSONException { if (branchingActivity.isChosenBranchingActivity()) { branchingActivity.setSystemTool(getSystemTool(SystemTool.TEACHER_CHOSEN_BRANCHING)); } else if (branchingActivity.isGroupBranchingActivity()) { @@ -2164,11 +2078,11 @@ } private void buildGroupingActivity(GroupingActivity groupingActivity, JSONObject activityDetails) - throws ObjectExtractorException { + throws ObjectExtractorException, JSONException { /** * read the createGroupingUUID, get the Grouping Object, and set CreateGrouping to that object */ - Integer createGroupingUIID = activityDetails.optInt(AuthoringJsonTags.CREATE_GROUPING_UIID); + Integer createGroupingUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.CREATE_GROUPING_UIID); Grouping grouping = groupings.get(createGroupingUIID); if (grouping != null) { groupingActivity.setCreateGrouping(grouping); @@ -2195,10 +2109,11 @@ } } - private void buildOptionsActivity(OptionsActivity optionsActivity, JSONObject activityDetails) { - optionsActivity.setMaxNumberOfOptions(activityDetails.optInt(AuthoringJsonTags.MAX_OPTIONS)); - optionsActivity.setMinNumberOfOptions(activityDetails.optInt(AuthoringJsonTags.MIN_OPTIONS)); - optionsActivity.setOptionsInstructions(activityDetails.optString(AuthoringJsonTags.OPTIONS_INSTRUCTIONS)); + private void buildOptionsActivity(OptionsActivity optionsActivity, JSONObject activityDetails) throws JSONException { + optionsActivity.setMaxNumberOfOptions((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.MAX_OPTIONS)); + optionsActivity.setMinNumberOfOptions((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.MIN_OPTIONS)); + optionsActivity.setOptionsInstructions((String) JsonUtil.opt(activityDetails, + AuthoringJsonTags.OPTIONS_INSTRUCTIONS)); } private void buildParallelActivity(ParallelActivity activity) { @@ -2226,11 +2141,11 @@ private void buildToolActivity(ToolActivity toolActivity, JSONObject activityDetails) throws JSONException { if (log.isDebugEnabled()) { - log.debug("In tool activity UUID " + activityDetails.opt(AuthoringJsonTags.ACTIVITY_UIID) - + " tool content id=" + activityDetails.get(AuthoringJsonTags.TOOL_CONTENT_ID)); + log.debug("In tool activity UUID " + JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_UIID) + + " tool content id " + JsonUtil.opt(activityDetails, AuthoringJsonTags.TOOL_CONTENT_ID)); } - toolActivity.setToolContentId(activityDetails.optLong(AuthoringJsonTags.TOOL_CONTENT_ID)); - Tool tool = toolDAO.getToolByID(activityDetails.getLong(AuthoringJsonTags.TOOL_ID)); + toolActivity.setToolContentId(JsonUtil.optLong(activityDetails, AuthoringJsonTags.TOOL_CONTENT_ID)); + Tool tool = toolDAO.getToolByID(JsonUtil.optLong(activityDetails, AuthoringJsonTags.TOOL_ID)); toolActivity.setTool(tool); } @@ -2266,8 +2181,9 @@ buildScheduleGateActivity((ScheduleGateActivity) activity, activityDetails); } GateActivity gateActivity = (GateActivity) activity; - gateActivity.setGateActivityLevelId(activityDetails.getInt(AuthoringJsonTags.GATE_ACTIVITY_LEVEL_ID)); - gateActivity.setGateOpen(activityDetails.getBoolean(AuthoringJsonTags.GATE_OPEN)); + gateActivity.setGateActivityLevelId((Integer) JsonUtil.opt(activityDetails, + AuthoringJsonTags.GATE_ACTIVITY_LEVEL_ID)); + gateActivity.setGateOpen((Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.GATE_OPEN)); } @@ -2295,8 +2211,8 @@ private void buildScheduleGateActivity(ScheduleGateActivity activity, JSONObject activityDetails) throws JSONException { - activity.setGateStartTimeOffset(activityDetails.getLong(AuthoringJsonTags.GATE_START_OFFSET)); - activity.setGateEndTimeOffset(activityDetails.getLong(AuthoringJsonTags.GATE_END_OFFSET)); + activity.setGateStartTimeOffset(JsonUtil.optLong(activityDetails, AuthoringJsonTags.GATE_START_OFFSET)); + activity.setGateEndTimeOffset(JsonUtil.optLong(activityDetails, AuthoringJsonTags.GATE_END_OFFSET)); SystemTool systemTool = getSystemTool(SystemTool.SCHEDULE_GATE); activity.setSystemTool(systemTool); } @@ -2311,8 +2227,8 @@ } } - private void createLessonClass(LessonClass lessonClass, JSONObject groupingDetails) { - Long groupId = groupingDetails.optLong(AuthoringJsonTags.STAFF_GROUP_ID); + private void createLessonClass(LessonClass lessonClass, JSONObject groupingDetails) throws JSONException { + Long groupId = JsonUtil.optLong(groupingDetails, AuthoringJsonTags.STAFF_GROUP_ID); if (groupId != null) { Group group = groupDAO.getGroupById(groupId); if (group != null) { @@ -2467,8 +2383,8 @@ transition.setFromUIID(null); } - transition.setDescription(transitionDetails.optString(AuthoringJsonTags.DESCRIPTION)); - transition.setTitle(transitionDetails.optString(AuthoringJsonTags.TITLE)); + transition.setDescription((String) JsonUtil.opt(transitionDetails, AuthoringJsonTags.DESCRIPTION)); + transition.setTitle((String) JsonUtil.opt(transitionDetails, AuthoringJsonTags.TITLE)); // Set creation date based on the server timezone, not the client. if (transition.getCreateDateTime() == null) { @@ -2785,7 +2701,8 @@ Integer entryUIID = details.getInt(AuthoringJsonTags.BRANCH_ACTIVITY_ENTRY_UIID); Integer sequenceActivityUIID = details.getInt(AuthoringJsonTags.BRANCH_SEQUENCE_ACTIVITY_UIID); - Boolean gateOpenWhenConditionMet = details.optBoolean(AuthoringJsonTags.BRANCH_GATE_OPENS_WHEN_CONDITION_MET); + Boolean gateOpenWhenConditionMet = (Boolean) JsonUtil.opt(details, + AuthoringJsonTags.BRANCH_GATE_OPENS_WHEN_CONDITION_MET); Integer branchingActivityUIID = null; if (gateOpenWhenConditionMet != null) { branchingActivityUIID = details.getInt(AuthoringJsonTags.BRANCH_GATE_ACTIVITY_UIID); @@ -2995,7 +2912,7 @@ if (conditionDetails != null) { - Long conditionID = conditionDetails.optLong(AuthoringJsonTags.CONDITION_ID); + Long conditionID = JsonUtil.optLong(conditionDetails, AuthoringJsonTags.CONDITION_ID); if (entry != null) { condition = entry.getCondition(); } @@ -3089,15 +3006,16 @@ learnerChoiceGrouping.setViewStudentsBeforeSelection(viewStudentsBeforeSelection); } - private void createLearnerChoiceGrouping(LearnerChoiceGrouping learnerChoiceGrouping, JSONObject groupingDetails) { - Integer numLearnersPerGroup = groupingDetails.optInt(AuthoringJsonTags.LEARNERS_PER_GROUP); + private void createLearnerChoiceGrouping(LearnerChoiceGrouping learnerChoiceGrouping, JSONObject groupingDetails) + throws JSONException { + Integer numLearnersPerGroup = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); if ((numLearnersPerGroup != null) && (numLearnersPerGroup.intValue() > 0)) { learnerChoiceGrouping.setLearnersPerGroup(numLearnersPerGroup); learnerChoiceGrouping.setNumberOfGroups(null); learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(null); } else { - Integer numGroups = groupingDetails.optInt(AuthoringJsonTags.NUMBER_OF_GROUPS); + Integer numGroups = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); if ((numGroups != null) && (numGroups.intValue() > 0)) { learnerChoiceGrouping.setNumberOfGroups(numGroups); @@ -3106,13 +3024,14 @@ } learnerChoiceGrouping.setLearnersPerGroup(null); - Boolean equalNumberOfLearnersPerGroup = groupingDetails.optBoolean(AuthoringJsonTags.NUMBER_OF_GROUPS); + Boolean equalNumberOfLearnersPerGroup = (Boolean) JsonUtil.opt(groupingDetails, + AuthoringJsonTags.NUMBER_OF_GROUPS); if (equalNumberOfLearnersPerGroup != null) { learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(equalNumberOfLearnersPerGroup); } } - learnerChoiceGrouping.setViewStudentsBeforeSelection(groupingDetails - .optBoolean(AuthoringJsonTags.VIEW_STUDENTS_BEFORE_SELECTION)); + learnerChoiceGrouping.setViewStudentsBeforeSelection((Boolean) JsonUtil.opt(groupingDetails, + AuthoringJsonTags.VIEW_STUDENTS_BEFORE_SELECTION)); } private void buildConditionGateActivity(ConditionGateActivity activity) { Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java,v diff -u -r1.40 -r1.41 --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java 29 Nov 2013 13:32:52 -0000 1.40 +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java 3 Dec 2013 20:30:00 -0000 1.41 @@ -41,13 +41,16 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; +import org.apache.tomcat.util.json.JSONArray; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.authoring.ObjectExtractorException; import org.lamsfoundation.lams.authoring.service.IAuthoringService; import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.learningdesign.dto.AuthoringActivityDTO; import org.lamsfoundation.lams.learningdesign.dto.LearningDesignDTO; import org.lamsfoundation.lams.learningdesign.dto.LicenseDTO; +import org.lamsfoundation.lams.learningdesign.dto.ValidationErrorDTO; import org.lamsfoundation.lams.learningdesign.service.ILearningDesignService; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.monitoring.service.IMonitoringService; @@ -446,14 +449,32 @@ } public ActionForward saveLearningDesign(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, UserException, WorkspaceFolderException, IOException, ObjectExtractorException, ParseException { + HttpServletResponse response) throws JSONException, UserException, WorkspaceFolderException, IOException, + ObjectExtractorException, ParseException { JSONObject ldJSON = new JSONObject(request.getParameter("ld")); LearningDesign learningDesign = getAuthoringService().saveLearningDesignDetails(ldJSON); - ldJSON.put(AttributeNames.PARAM_LEARNINGDESIGN_ID, learningDesign.getLearningDesignId()); - + + JSONObject responseJSON = new JSONObject(); + if (learningDesign != null) { + Long learningDesignID = learningDesign.getLearningDesignId(); + if (learningDesignID != null) { + responseJSON.put(AttributeNames.PARAM_LEARNINGDESIGN_ID, learningDesignID); + responseJSON.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, learningDesign.getContentFolderID()); + + Vector activityDTOs = getAuthoringService().getToolActivities(learningDesignID, + getUserLanguage()); + Vector validationDTOs =getAuthoringService().validateLearningDesign(learningDesignID); + Gson gson = new GsonBuilder().create(); + String activitiesJSON = gson.toJson(activityDTOs); + String validationJSON = gson.toJson(validationDTOs); + responseJSON.put("activities", new JSONArray(activitiesJSON)); + responseJSON.put("validation", new JSONArray(validationJSON)); + } + } + response.setContentType("application/json;charset=utf-8"); - response.getWriter().write(ldJSON.toString()); + response.getWriter().write(responseJSON.toString()); return null; } Index: lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java,v diff -u -r1.55 -r1.56 --- lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java 21 Oct 2013 13:47:28 -0000 1.55 +++ lams_central/src/java/org/lamsfoundation/lams/web/HomeAction.java 3 Dec 2013 20:30:00 -0000 1.56 @@ -189,20 +189,22 @@ learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_MODE, mode); } - learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_EXPORT_PORTFOLIO_ENABLED, String - .valueOf(lesson.getLearnerExportAvailable() != null ? lesson.getLearnerExportAvailable() + learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_EXPORT_PORTFOLIO_ENABLED, + String.valueOf(lesson.getLearnerExportAvailable() != null ? lesson.getLearnerExportAvailable() : Boolean.TRUE)); learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_PRESENCE_ENABLED, String.valueOf(lesson.getLearnerPresenceAvailable())); learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_PRESENCE_IM_ENABLED, String.valueOf(lesson.getLearnerImAvailable())); - learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_TITLE, lesson.getLessonName()); + learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_TITLE, + lesson.getLessonName()); /* Date Format for Chat room append */ DateFormat sfm = new SimpleDateFormat("yyyyMMdd_HHmmss"); learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_CREATE_DATE_TIME, sfm.format(lesson.getCreateDateTime())); - learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_LESSON_ID, String.valueOf(lessonId)); + learnerURL = WebUtil.appendParameterToURL(learnerURL, AttributeNames.PARAM_LESSON_ID, + String.valueOf(lessonId)); // show lesson intro page if required if (lesson.isEnableLessonIntro()) { @@ -330,7 +332,7 @@ UserDTO userDTO = getUser(); // get all user accessible folders and LD descriptions as JSON - JSONObject learningDesigns = getFolderContents(null, userDTO.getUserID()); + JSONObject learningDesigns = getFolderContents(null, userDTO.getUserID(), false); req.setAttribute("folderContents", learningDesigns.toString()); Integer organisationID = new Integer(WebUtil.readIntParam(req, "organisationID")); @@ -390,7 +392,8 @@ HttpServletResponse res) throws UserAccessDeniedException, JSONException, IOException, RepositoryCheckedException { Integer folderID = WebUtil.readIntParam(req, "folderID", true); - JSONObject responseJSON = getFolderContents(folderID, getUser().getUserID()); + boolean allowInvalidDesigns = WebUtil.readBooleanParam(req, "allowInvalidDesigns", false); + JSONObject responseJSON = getFolderContents(folderID, getUser().getUserID(), allowInvalidDesigns); res.setContentType("application/json;charset=utf-8"); res.getWriter().print(responseJSON.toString()); @@ -421,8 +424,8 @@ } @SuppressWarnings("unchecked") - private JSONObject getFolderContents(Integer folderID, Integer userID) throws JSONException, IOException, - UserAccessDeniedException, RepositoryCheckedException { + private JSONObject getFolderContents(Integer folderID, Integer userID, boolean allowInvalidDesigns) + throws JSONException, IOException, UserAccessDeniedException, RepositoryCheckedException { JSONObject result = new JSONObject(); Vector folderContents = null; @@ -454,13 +457,14 @@ if (folderContents.size() == 1) { FolderContentDTO folder = folderContents.firstElement(); if (folder.getResourceID().equals(WorkspaceAction.ROOT_ORG_FOLDER_ID)) { - return getFolderContents(WorkspaceAction.ROOT_ORG_FOLDER_ID, userID); + return getFolderContents(WorkspaceAction.ROOT_ORG_FOLDER_ID, userID, allowInvalidDesigns); } } } else { WorkspaceFolder folder = getWorkspaceManagementService().getWorkspaceFolder(folderID); - folderContents = getWorkspaceManagementService().getFolderContents(userID, folder, - WorkspaceManagementService.MONITORING); + Integer mode = allowInvalidDesigns ? WorkspaceManagementService.AUTHORING + : WorkspaceManagementService.MONITORING; + folderContents = getWorkspaceManagementService().getFolderContents(userID, folder, mode); Collections.sort(folderContents); } Index: lams_central/web/author2.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/Attic/author2.jsp,v diff -u -r1.15 -r1.16 --- lams_central/web/author2.jsp 29 Nov 2013 13:32:52 -0000 1.15 +++ lams_central/web/author2.jsp 3 Dec 2013 20:30:00 -0000 1.16 @@ -55,7 +55,7 @@
 
    -
  • Save as...
  • +
  • Save as...
@@ -85,10 +85,11 @@
Arrange
+
@@ -105,6 +106,7 @@
@@ -221,22 +223,6 @@ - - - Offline Activity: - - - - - - - - Define in Monitor: - - - - -
Index: lams_central/web/includes/javascript/authoring/authoringActivity.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringActivity.js,v diff -u -r1.10 -r1.11 --- lams_central/web/includes/javascript/authoring/authoringActivity.js 29 Nov 2013 13:32:52 -0000 1.10 +++ lams_central/web/includes/javascript/authoring/authoringActivity.js 3 Dec 2013 20:30:00 -0000 1.11 @@ -7,10 +7,12 @@ /** * Constructor for a Tool Activity. */ - ToolActivity: function(id, toolID, x, y, title, supportsOutputs) { - this.id = id; + ToolActivity : function(id, uiid, toolContentID, toolID, x, y, title, supportsOutputs) { + this.id = +id; + this.uiid = +uiid || ++layout.maxUIID; + this.toolContentID = toolContentID; this.type = 'tool'; - this.toolID = toolID; + this.toolID = +toolID; this.title = title; this.supportsOutputs = supportsOutputs; this.transitions = { @@ -27,16 +29,17 @@ /** * Constructor for a Grouping Activity. */ - GroupingActivity : function(id, x, y, title, groupingID, groupingType, groupDivide, groupCount, learnerCount, + GroupingActivity : function(id, uiid, x, y, title, groupingID, groupingType, groupDivide, groupCount, learnerCount, equalSizes, viewLearners, groups) { - this.id = id; - this.groupingID = groupingID; + this.id = +id; + this.uiid = +uiid || ++layout.maxUIID; + this.groupingID = +groupingID; this.type = 'grouping'; this.title = title; this.groupingType = groupingType || 'random'; this.groupDivide = groupDivide || 'groups'; - this.groupCount = groupCount || 2; - this.learnerCount = learnerCount || 1; + this.groupCount = +groupCount || 2; + this.learnerCount = +learnerCount || 1; this.equalSizes = equalSizes || false; this.viewLearners = viewLearners || false; this.groups = groups || []; @@ -54,8 +57,9 @@ /** * Constructor for a Gate Activity. */ - GateActivity : function(id, x, y, gateType) { - this.id = id; + GateActivity : function(id, uiid, x, y, gateType) { + this.id = +id; + this.uiid = +uiid || ++layout.maxUIID; this.type = 'gate'; this.gateType = gateType || 'permission'; this.transitions = { @@ -73,7 +77,7 @@ /** * Either branching or converge point. */ - BranchingEdgeActivity : function(id, x, y, title, branchingType, branchingActivity) { + BranchingEdgeActivity : function(id, uiid, x, y, title, branchingType, branchingActivity) { this.type = 'branchingEdge'; this.transitions = { 'from' : [], @@ -87,7 +91,7 @@ } else { // this is the branching point this.isStart = true; - branchingActivity = new ActivityLib.BranchingActivity(id, this); + branchingActivity = new ActivityLib.BranchingActivity(id, uiid, this); branchingActivity.branchingType = branchingType || 'chosen'; branchingActivity.title = title || 'Branching'; } @@ -103,8 +107,9 @@ /** * Represents a set of branches. It is not displayed on canvas. */ - BranchingActivity : function(id, branchingEdgeStart) { - this.id = id; + BranchingActivity : function(id, uiid, branchingEdgeStart) { + this.id = +id; + this.uiid = +uiid || ++layout.maxUIID; this.start = branchingEdgeStart; this.branches = []; // mapping between groups and branches, if applicable @@ -116,8 +121,8 @@ * Represents a subsequence of activities. It is not displayed on canvas. */ BranchActivity : function(id, uiid, title, branchingActivity, transitionFrom) { - this.id = id; - this.uiid = uiid; + this.id = +id; + this.uiid = +uiid || ++layout.maxUIID; this.title = title; this.transitionFrom = transitionFrom; this.branchingActivity = branchingActivity; @@ -143,12 +148,12 @@ paper.setStart(); var shape = paper.path(Raphael.format('M {0} {1}' + layout.defs.activity, x, y)) .attr({ - 'fill' : this.offline ? layout.colors.offlineActivity : layout.colors.activity + 'fill' : layout.colors.activity[layout.toolMetadata[this.toolID].activityCategoryID] }); paper.image(layout.toolMetadata[this.toolID].iconPath, x + 47, y + 2, 30, 30); paper.text(x + 62, y + 40, ActivityLib.shortenActivityTitle(this.title)) .attr({ - 'fill' : this.offline ? layout.colors.offlineActivityText : layout.colors.activityText + 'fill' : layout.colors.activityText }); this.items = paper.setFinish(); @@ -329,7 +334,7 @@ /** * Draws a transition between two activities. */ - drawTransition : function(fromActivity, toActivity, redraw) { + drawTransition : function(fromActivity, toActivity, redraw, id, uiid) { // only converge points are allowed to have few inbound transitions if (!redraw && toActivity.transitions.to.length > 0 @@ -353,6 +358,7 @@ // remove the existing transition $.each(fromActivity.transitions.from, function(index) { if (this.toActivity == toActivity) { + uiid = this.uiid; ActivityLib.removeTransition(this); return false; } @@ -379,6 +385,8 @@ 'fill' : layout.colors.transition }); var transition = paper.setFinish(); + transition.uiid = uiid || ++layout.maxUIID; + transition.id = id; transition.data('transition', transition); // set up references in activities and the transition @@ -593,7 +601,7 @@ }, success : function(response) { activity.authorURL = response.authorURL; - activity.id = response.toolContentID; + activity.toolContentID = response.toolContentID; if (!layout.contentFolderID) { // if LD did not have contentFolderID, it was just generated // so remember it Index: lams_central/web/includes/javascript/authoring/authoringGeneral.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringGeneral.js,v diff -u -r1.9 -r1.10 --- lams_central/web/includes/javascript/authoring/authoringGeneral.js 29 Nov 2013 13:32:52 -0000 1.9 +++ lams_central/web/includes/javascript/authoring/authoringGeneral.js 3 Dec 2013 20:30:00 -0000 1.10 @@ -4,11 +4,12 @@ // few publicly visible variables var paper = null, - canvas = null; - + canvas = null, + // configuration and storage of various elements -var layout = { - 'isZoomed' : false, + layout = { + 'maxUIID' : 0, + // 'isZoomed' : false, 'activities' : null, 'items' : { 'bin' : null, @@ -49,7 +50,7 @@ 'bin' : 'M 0 0 h -50 l 10 50 h 30 z' }, 'colors' : { - 'activity' : '#A9C8FD', + 'activity' : ['','#d0defd','#fffccb','#ece9f7','#fdf1d3','#FFFFFF','#e9f9c0'], 'offlineActivity' : 'black', 'activityText' : 'black', 'offlineActivityText' : 'white', @@ -84,11 +85,12 @@ */ function initTemplates(){ $('.template').each(function(){ - var toolId = $(this).attr('toolId'); + var toolId = +$(this).attr('toolId'); // register tool properties so they are later easily accessible layout.toolMetadata[toolId] = { - 'iconPath' : $('img', this).attr('src'), - 'supportsOutputs' : $(this).attr('supportsOutputs') + 'iconPath' : $('img', this).attr('src'), + 'supportsOutputs' : $(this).attr('supportsOutputs'), + 'activityCategoryID' : +$(this).attr('activityCategoryID') }; // if a tool's name is too long and gets broken into two lines @@ -136,7 +138,7 @@ y = draggable.offset.top + canvas.scrollTop() - canvas.offset().top, label = $('div', draggable.draggable).text(); - layout.activities.push(new ActivityLib.ToolActivity(null, toolID, x, y, label)); + layout.activities.push(new ActivityLib.ToolActivity(null, null, null, toolID, x, y, label)); } }); } @@ -218,7 +220,7 @@ learningDesingID = node.data.learningDesignId && nodeTitle == title ? node.data.learningDesignId : null; if (learningDesingID - && !confirm('Are you sure you want to overwrite an existing sequence?')) { + && !confirm('Are you sure you want to overwrite the existing sequence?')) { return; } @@ -227,8 +229,10 @@ folderID = node.parent.data.folderID; } - dialog.dialog('close'); - saveLearningDesign(folderID, learningDesingID, title); + var result = saveLearningDesign(folderID, learningDesingID, title); + if (result) { + dialog.dialog('close'); + } } }, closeLdStoreDialogButton @@ -254,8 +258,10 @@ ldStoreDialog.dialog('option', 'ldTree', tree); // make folder contents load dynamically on open tree.setDynamicLoad(function(node, callback){ + var dialog = $(this.getEl()).closest('.ui-dialog'), + isSaveDialog = dialog.hasClass('ldStoreDialogSave'); // load subfolder contents - var childNodeData = MenuLib.getFolderContents(node.data.folderID); + var childNodeData = MenuLib.getFolderContents(node.data.folderID, isSaveDialog); if (childNodeData) { $.each(childNodeData, function(){ // create and add a leaf @@ -353,11 +359,18 @@ $.each(ld.activities, function() { var activityData = this, activity = null; + + // find max uiid so newly created elements have, unique ones + if (activityData.activityUIID && layout.maxUIID < activityData.activityUIID) { + layout.maxUIID = activityData.activityUIID; + } switch(activityData.activityTypeID) { // Tool Activity case 1 : activity = new ActivityLib.ToolActivity(activityData.activityID, + activityData.activityUIID, + activityData.toolContentID, activityData.toolID, activityData.xCoord, activityData.yCoord, @@ -398,6 +411,7 @@ }); activity = new ActivityLib.GroupingActivity(activityData.activityID, + activityData.activityUIID, activityData.xCoord, activityData.yCoord, activityData.activityTitle, @@ -421,6 +435,7 @@ case 6: var gateType = gateType || 'condition'; activity = new ActivityLib.GateActivity(activityData.activityID, + activityData.activityUIID, activityData.xCoord, activityData.yCoord, gateType); @@ -433,8 +448,11 @@ // draw both edge points straight away and mark the whole canvas for auto reaarange arrangeNeeded = true; var branchingType = branchingType || 'tool', - branchingEdge = new ActivityLib.BranchingEdgeActivity(activityData.activityID, 0, 0, - activityData.activityTitle, branchingType, null); + branchingEdge = new ActivityLib.BranchingEdgeActivity(activityData.activityID, + activityData.activityUIID, + 0, 0, + activityData.activityTitle, + branchingType); layout.activities.push(branchingEdge); // for later reference activityData.activity = branchingEdge; @@ -607,7 +625,8 @@ // found both transition ends, draw it and stop the iteration if (fromActivity && toActivity) { - ActivityLib.drawTransition(fromActivity, toActivity, true); + ActivityLib.drawTransition(fromActivity, toActivity, true, + transition.transitionID, transition.transitionUIID); return false; } }); @@ -630,35 +649,88 @@ * Stores the sequece into database. */ function saveLearningDesign(folderID, learningDesignID, title) { + var activities = [], + transitions = [], + result = false; + + $.each(layout.activities, function(){ + var activity = this, + activityBox = activity.items.shape.getBBox(), + toolID = activity.toolID, + iconPath = null; + if (toolID) { + var templateIcon = $('.template[toolId=' + toolID +'] img'); + if (templateIcon.width() > 0) { + // iconPath = layout.toolMetadata[toolID].iconPath; + } + } + + + activities.push({ + 'activityID' : activity.id, + 'activityUIID' : activity.uiid, + 'toolID' : toolID, + 'learningLibraryID' : toolID, + 'toolContentID' : activity.toolContentID, + 'stopAfterActivity' : false, + 'groupingSupportType' : 2, + 'applyGrouping' : false, + 'parentActivityID' : null, + 'parentUIID' : null, + 'libraryActivityUIImage' : iconPath, + 'xCoord' : activityBox.x, + 'yCoord' : activityBox.y, + 'activityTitle' : activity.title, + 'activityCategoryID' : layout.toolMetadata[toolID].activityCategoryID, + 'activityTypeID' : 1, + + 'gradebookToolOutputDefinitionName' : null, + 'helpText' : null, + 'description' : null + }); + + $.each(activity.transitions.from, function(){ + var transition = this; + + transitions.push({ + 'transitionID' : transition.id, + 'transitionUIID' : transition.uiid, + 'fromUIID' : activity.uiid, + 'toUIID' : transition.toActivity.uiid, + 'transitionType' : 0 + }); + }); + }); + // serialise the sequence var ld = { // it is null if it is a new sequence 'learningDesignID' : learningDesignID, 'workspaceFolderID' : folderID, 'copyTypeID' : 1, 'originalUserID' : null, - 'learningDesignUIID' : null, 'title' : title.trim(), 'description' : $('#ldDescriptionFieldDescription').val().trim(), - 'maxID' : null, + 'maxID' : layout.maxUIID, 'readOnly' : false, 'editOverrideLock' : false, 'dateReadOnly' : null, - 'helpText' : null, 'version' : null, - 'duration' : null, 'contentFolderID' : layout.contentFolderID, 'saveMode' : 0, - 'licenseID' : null, - 'licenseText' : null, 'originalLearningDesignID' : null, - 'activities' : null, - 'transitions' : null, + 'activities' : activities, + 'transitions' : transitions, 'groupings' : null, 'branchMappings' : null, - 'competences' : null, - 'competenceMappings' : null + + 'learningDesignUIID' : null, + 'helpText' : null, + 'duration' : null, + 'licenseID' : null, + 'licenseText' : null + }; // get LD details @@ -669,12 +741,55 @@ dataType : 'json', data : { 'method' : 'saveLearningDesign', - 'ld' : ld + 'ld' : JSON.stringify(ld) }, - success : function(responseLd) { - + success : function(response) { + if (response.learningDesignID) { + layout.learningDesignID = response.learningDesignID; + layout.folderID = folderID; + layout.title = title; + if (!layout.contentFolderID) { + layout.contentFolderID = response.contentFolderID; + } + if (response.validation.length > 0) { + var message = 'While saving the sequence there were following validation issues:\n'; + $.each(response.validation, function() { + var uiid = this.UIID, + title = ''; + $.each(layout.activities, function(){ + if (uiid == this.uiid) { + title = this.title + ': '; + } + }); + message += title + this.message + '\n'; + }); + + alert(message); + return; + } + + $.each(response.activities, function() { + var updatedActivity = this; + $.each(layout.activities, function(){ + var activity = this; + if (updatedActivity.activityUIID == activity.uiid) { + activity.id = updatedActivity.activityID; + activity.toolContentID = updatedActivity.toolContentID; + } + }); + }); + + result = true; + } else { + alert('Error while saving the sequence'); + } + }, + error : function(){ + alert('Error while saving the sequence'); } }); + + return result; } Index: lams_central/web/includes/javascript/authoring/authoringMenu.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringMenu.js,v diff -u -r1.9 -r1.10 --- lams_central/web/includes/javascript/authoring/authoringMenu.js 29 Nov 2013 13:32:52 -0000 1.9 +++ lams_central/web/includes/javascript/authoring/authoringMenu.js 3 Dec 2013 20:30:00 -0000 1.10 @@ -158,7 +158,14 @@ /** * Opens "Save sequence" dialog where an user can choose where to save the Learning Design. */ - saveLearningDesign : function(){ + saveLearningDesign : function(showDialog){ + if (!showDialog && layout.learningDesignID) { + if (confirm('Are you sure you want to overwrite the existing sequence?')) { + saveLearningDesign(layout.folderID, layout.learningDesignID, layout.title); + } + return; + } + var dialog = $('#ldStoreDialog'); // remove the directory tree, if it remained for last dialog opening dialog.dialog('option', { @@ -169,7 +176,8 @@ }) .dialog('open'); - MenuLib.initLearningDesignTree(); + var tree = MenuLib.initLearningDesignTree(); + tree.getRoot().children[0].highlight(); }, @@ -190,20 +198,23 @@ // expand the first (user) folder tree.getRoot().children[0].expand(); + + return tree; }, /** * Loads subfolders and LDs from the server. */ - getFolderContents : function(folderID) { + getFolderContents : function(folderID, allowInvalidDesigns) { var result = null; $.ajax({ url : LAMS_URL + 'home.do', data : { 'method' : 'getFolderContents', - 'folderID' : folderID + 'folderID' : folderID, + 'allowInvalidDesigns' : allowInvalidDesigns }, cache : false, async: false, @@ -447,6 +458,7 @@ $('.ldDescriptionField').text(''); + layout.maxUIID = 0; layout.activities = []; if (paper) { paper.clear(); @@ -517,10 +529,10 @@ newActivity.grouping = activity.grouping; newActivity.draw(); } - }, + } - - zoom : function(){ + /* + ,zoom : function(){ var zoomButton = $('#zoomButton > span'); if (layout.isZoomed) { paper.setViewBox(0, 0, paper.width, paper.height, true); @@ -532,4 +544,5 @@ zoomButton.text('Cancel zoom'); } } + */ }; \ No newline at end of file Index: lams_central/web/includes/javascript/authoring/authoringProperty.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/authoring/authoringProperty.js,v diff -u -r1.2 -r1.3 --- lams_central/web/includes/javascript/authoring/authoringProperty.js 26 Nov 2013 17:30:00 -0000 1.2 +++ lams_central/web/includes/javascript/authoring/authoringProperty.js 3 Dec 2013 20:30:00 -0000 1.3 @@ -166,14 +166,6 @@ activity.grouping = newGroupingValue; redrawNeeded = true; } - activity.defineInMonitor = $('.propertiesContentFieldDefineMonitor', content) - .is(':checked'); - var newOfflineValue = $('.propertiesContentFieldOffline', content) - .is(':checked'); - if (newOfflineValue != activity.offline) { - activity.offline = newOfflineValue; - redrawNeeded = true; - } if (redrawNeeded) { activity.draw(); Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/LearningDesignService.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/LearningDesignService.java,v diff -u -r1.27 -r1.28 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/LearningDesignService.java 20 Nov 2013 16:33:25 -0000 1.27 +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/LearningDesignService.java 3 Dec 2013 20:29:57 -0000 1.28 @@ -222,6 +222,7 @@ ToolDTO toolDTO = new ToolDTO(); toolDTO.setToolId(learningLibrary.getLearningLibraryID()); toolDTO.setToolDisplayName(libraryActivityDTO.getActivityTitle()); + toolDTO.setActivityCategoryID(libraryActivityDTO.getActivityCategoryID()); Tool tool = (Tool) learningLibraryDAO.find(Tool.class, learningLibrary.getLearningLibraryID()); if (tool != null) { Index: lams_common/src/java/org/lamsfoundation/lams/tool/dto/ToolDTO.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/tool/dto/ToolDTO.java,v diff -u -r1.2 -r1.3 --- lams_common/src/java/org/lamsfoundation/lams/tool/dto/ToolDTO.java 20 Nov 2013 16:33:25 -0000 1.2 +++ lams_common/src/java/org/lamsfoundation/lams/tool/dto/ToolDTO.java 3 Dec 2013 20:29:57 -0000 1.3 @@ -23,12 +23,12 @@ /* $Id$ */ package org.lamsfoundation.lams.tool.dto; - public class ToolDTO { private Long toolId; private String toolDisplayName; private String iconPath; private Boolean supportsOutputs; + private Integer activityCategoryID; public ToolDTO() { } @@ -48,7 +48,7 @@ public void setToolDisplayName(String displayName) { this.toolDisplayName = displayName; } - + public String getIconPath() { return iconPath; } @@ -58,10 +58,18 @@ } public Boolean getSupportsOutputs() { - return supportsOutputs; + return supportsOutputs; } public void setSupportsOutputs(Boolean supportsOutputs) { - this.supportsOutputs = supportsOutputs; + this.supportsOutputs = supportsOutputs; } + + public Integer getActivityCategoryID() { + return activityCategoryID; + } + + public void setActivityCategoryID(Integer activityCategoryID) { + this.activityCategoryID = activityCategoryID; + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/AuthoringJsonTags.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/util/AuthoringJsonTags.java,v diff -u -r1.1 -r1.2 --- lams_common/src/java/org/lamsfoundation/lams/util/AuthoringJsonTags.java 29 Nov 2013 13:32:56 -0000 1.1 +++ lams_common/src/java/org/lamsfoundation/lams/util/AuthoringJsonTags.java 3 Dec 2013 20:29:57 -0000 1.2 @@ -35,9 +35,6 @@ public static final String GROUPINGS = "groupings"; public static final String TRANSITIONS = "transitions"; public static final String ACTIVITIES = "activities"; - public static final String COMPETENCES = "competences"; - public static final String COMPETENCE_MAPPINGS = "competenceMappings"; - public static final String COMPETENCE_MAPPING = "competenceMapping"; public static final String BRANCH_MAPPINGS = "branchMappings"; /* Learning Library specific tags */ @@ -59,10 +56,6 @@ public static final String ACTIVITY_CATEGORY_ID = "activityCategoryID"; - public static final String DEFINE_LATER = "defineLater"; - public static final String RUN_OFFLINE = "runOffline"; - public static final String OFFLINE_INSTRUCTIONS = "offlineInstructions"; - public static final String ONLINE_INSTRUCTIONS = "onlineInstructions"; public static final String LIBRARY_IMAGE = "libraryActivityUIImage"; public static final String LIBRARY_ACTIVITY = "libraryActivityID"; Index: lams_common/src/java/org/lamsfoundation/lams/util/JsonUtil.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/util/JsonUtil.java,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lams_common/src/java/org/lamsfoundation/lams/util/JsonUtil.java 3 Dec 2013 20:29:57 -0000 1.1 @@ -0,0 +1,71 @@ +/**************************************************************** + * 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: JsonUtil.java,v 1.1 2013/12/03 20:29:57 marcin Exp $$ */ +package org.lamsfoundation.lams.util; + +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; + +/** + * Helper for JSON objects. + * + * @author Marcin Cieslak + * + */ +public class JsonUtil { + + /** + * Checks if given key exists in JSON object and returns defaultValue otherwise. Native JSONObject.opt() method does + * not check for JSONNull value, so it had to be rewritten. + */ + @SuppressWarnings("unchecked") + public static T opt(JSONObject object, String field, T defaultValue) throws JSONException { + return object.isNull(field) ? defaultValue : (T) object.get(field); + } + + /** + * Checks if given key exists in JSON object and returns defaultValue otherwise. Native JSONObject.opt() method does + * not check for JSONNull value, so it had to be rewritten. + */ + public static Object opt(JSONObject object, String field) throws JSONException { + return object.isNull(field) ? null : object.get(field); + } + + /** + * Checks if long value for given key exists in JSON object and returns null otherwise. This special method prevents + * exception when casting Integer (JSON default type for numbers) to Long. Native JSONObject.opt() method does not + * check for JSONNull value, so it had to be rewritten. + */ + public static Long optLong(JSONObject object, String field) throws JSONException { + Object value = object.isNull(field) ? null : object.get(field); + if (value != null) { + if (value instanceof Number) { + value = ((Number) value).longValue(); + } else { + value = new Long((String) value); + } + } + + return (Long) value; + } +} \ No newline at end of file