Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -rbe118ba177d68f16232e2414606a569b398ee2a0 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c Binary files differ Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -r2d51ee8a959ecba6a2f6ac2da80b7b9857bc50d0 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 2d51ee8a959ecba6a2f6ac2da80b7b9857bc50d0) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -34,9 +34,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -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.dao.IBaseDAO; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; @@ -97,6 +94,10 @@ import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.JsonUtil; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Manpreet Minhas * @author Mailing Truong @@ -314,16 +315,16 @@ } @Override - public LearningDesign extractSaveLearningDesign(JSONObject ldJSON, LearningDesign existingLearningDesign, - WorkspaceFolder workspaceFolder, User user) throws ObjectExtractorException, ParseException, JSONException { + public LearningDesign extractSaveLearningDesign(ObjectNode ldJSON, LearningDesign existingLearningDesign, + WorkspaceFolder workspaceFolder, User user) throws ObjectExtractorException, ParseException { // 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 = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.COPY_TYPE); + Integer copyTypeID = JsonUtil.optInt(ldJSON, AuthoringJsonTags.COPY_TYPE); if (copyTypeID == null) { copyTypeID = LearningDesign.COPY_TYPE_NONE; } @@ -339,15 +340,15 @@ learningDesign.setWorkspaceFolder(workspaceFolder); learningDesign.setUser(user); - String contentFolderID = (String) JsonUtil.opt(ldJSON, AuthoringJsonTags.CONTENT_FOLDER_ID); + String contentFolderID = JsonUtil.optString(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 = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.ORIGINAL_USER_ID); + Integer originalUserID = JsonUtil.optInt(ldJSON, AuthoringJsonTags.ORIGINAL_USER_ID); if (originalUserID == null) { learningDesign.setOriginalUser(user); } else { @@ -375,25 +376,25 @@ initialiseToolSessionMap(learningDesign); // get the core learning design stuff - default to invalid - 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.setValidDesign(JsonUtil.optBoolean(ldJSON, AuthoringJsonTags.VALID_DESIGN, false)); + learningDesign.setLearningDesignUIID(JsonUtil.optInt(ldJSON, AuthoringJsonTags.LEARNING_DESIGN_UIID)); + learningDesign.setDescription(JsonUtil.optString(ldJSON, AuthoringJsonTags.DESCRIPTION)); + learningDesign.setTitle(JsonUtil.optString(ldJSON, AuthoringJsonTags.TITLE)); + learningDesign.setMaxID(JsonUtil.optInt(ldJSON, AuthoringJsonTags.MAX_ID)); + learningDesign.setReadOnly(JsonUtil.optBoolean(ldJSON, AuthoringJsonTags.READ_ONLY)); + learningDesign.setEditOverrideLock(JsonUtil.optBoolean(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); + DateUtil.convertFromString(JsonUtil.optString(ldJSON, AuthoringJsonTags.DATE_READ_ONLY))); + learningDesign.setHelpText(JsonUtil.optString(ldJSON, AuthoringJsonTags.HELP_TEXT)); + String version = JsonUtil.optString(ldJSON, AuthoringJsonTags.VERSION); if (version == null) { version = Configuration.get(ConfigurationKeys.SERVER_VERSION_NUMBER); } - learningDesign.setDesignType((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.DESIGN_TYPE)); + learningDesign.setDesignType(JsonUtil.optString(ldJSON, AuthoringJsonTags.DESIGN_TYPE)); learningDesign.setVersion(version); learningDesign.setDuration(JsonUtil.optLong(ldJSON, AuthoringJsonTags.DURATION)); - mode = (Integer) JsonUtil.opt(ldJSON, AuthoringJsonTags.SAVE_MODE); + mode = JsonUtil.optInt(ldJSON, AuthoringJsonTags.SAVE_MODE); // Set creation date and modification date based on the server timezone, // not the client. @@ -407,7 +408,7 @@ License license = licenseDAO.getLicenseByID(licenseID); learningDesign.setLicense(license); } - learningDesign.setLicenseText((String) JsonUtil.opt(ldJSON, AuthoringJsonTags.LICENSE_TEXT)); + learningDesign.setLicenseText(JsonUtil.optString(ldJSON, AuthoringJsonTags.LICENSE_TEXT)); Long originalLearningDesignID = JsonUtil.optLong(ldJSON, AuthoringJsonTags.ORIGINAL_DESIGN_ID); if (originalLearningDesignID != null) { @@ -418,13 +419,12 @@ learningDesignDAO.insertOrUpdate(learningDesign); // now process the "parts" of the learning design - 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)); - parseAnnotations((JSONArray) JsonUtil.opt(ldJSON, AuthoringJsonTags.ANNOTATIONS)); + parseGroupings(JsonUtil.optArray(ldJSON, AuthoringJsonTags.GROUPINGS)); + parseActivities(JsonUtil.optArray(ldJSON, AuthoringJsonTags.ACTIVITIES)); + parseActivitiesToMatchUpParentandInputActivities(JsonUtil.optArray(ldJSON, AuthoringJsonTags.ACTIVITIES)); + parseTransitions(JsonUtil.optArray(ldJSON, AuthoringJsonTags.TRANSITIONS)); + parseBranchMappings(JsonUtil.optArray(ldJSON, AuthoringJsonTags.BRANCH_MAPPINGS)); + parseAnnotations(JsonUtil.optArray(ldJSON, AuthoringJsonTags.ANNOTATIONS)); progressDefaultChildActivities(); @@ -587,25 +587,24 @@ } } - private void parseGroupings(JSONArray groupingsList) throws JSONException { + private void parseGroupings(ArrayNode groupingsList) { // iterate through the list of groupings objects // each object should contain information groupingUUID, groupingID, // groupingTypeID if (groupingsList != null) { - for (int groupingIndex = 0; groupingIndex < groupingsList.length(); groupingIndex++) { - JSONObject groupingDetails = groupingsList.getJSONObject(groupingIndex); + for (JsonNode groupingDetails : groupingsList) { if (groupingDetails != null) { - Grouping grouping = extractGroupingObject(groupingDetails); + Grouping grouping = extractGroupingObject((ObjectNode) groupingDetails); groupingDAO.insertOrUpdate(grouping); groupings.put(grouping.getGroupingUIID(), grouping); } } } } - public Grouping extractGroupingObject(JSONObject groupingDetails) throws JSONException { - Integer groupingUIID = (Integer) JsonUtil.opt(groupingDetails, "groupingUIID"); - Integer groupingTypeID = (Integer) JsonUtil.opt(groupingDetails, "groupingTypeID"); + public Grouping extractGroupingObject(ObjectNode groupingDetails) { + Integer groupingUIID = JsonUtil.optInt(groupingDetails, "groupingUIID"); + Integer groupingTypeID = JsonUtil.optInt(groupingDetails, "groupingTypeID"); Grouping grouping = groupings.get(groupingUIID); // check that the grouping type is still okay - if it is we keep the @@ -638,15 +637,14 @@ createLessonClass((LessonClass) grouping, groupingDetails); } - grouping.setMaxNumberOfGroups((Integer) JsonUtil.opt(groupingDetails, "maxNumberOfGroups")); + grouping.setMaxNumberOfGroups(JsonUtil.optInt(groupingDetails, "maxNumberOfGroups")); Set groupsToDelete = new HashSet<>(grouping.getGroups()); - JSONArray groupsList = (JSONArray) JsonUtil.opt(groupingDetails, "groups"); + ArrayNode groupsList = JsonUtil.optArray(groupingDetails, "groups"); if (groupsList != null) { - for (int groupIndex = 0; groupIndex < groupsList.length(); groupIndex++) { - JSONObject groupDetails = groupsList.getJSONObject(groupIndex); - Group group = extractGroupObject(groupDetails, grouping); + for (JsonNode groupDetails : groupsList) { + Group group = extractGroupObject((ObjectNode) groupDetails, grouping); groups.put(group.getGroupUIID(), group); groupsToDelete.remove(group); } @@ -670,10 +668,10 @@ return grouping; } - private Group extractGroupObject(JSONObject groupDetails, Grouping grouping) throws JSONException { + private Group extractGroupObject(ObjectNode groupDetails, Grouping grouping) { Group group = null; - Integer groupUIID = (Integer) JsonUtil.opt(groupDetails, AuthoringJsonTags.GROUP_UIID); + Integer groupUIID = JsonUtil.optInt(groupDetails, AuthoringJsonTags.GROUP_UIID); Long groupID = JsonUtil.optLong(groupDetails, AuthoringJsonTags.GROUP_ID); // Does it exist already? If the group was created at runtime, there @@ -705,23 +703,23 @@ grouping.getGroups().add(group); } - group.setGroupName((String) JsonUtil.opt(groupDetails, AuthoringJsonTags.GROUP_NAME)); + group.setGroupName(JsonUtil.optString(groupDetails, AuthoringJsonTags.GROUP_NAME)); group.setGrouping(grouping); group.setGroupUIID(groupUIID); - group.setOrderId(JsonUtil.opt(groupDetails, AuthoringJsonTags.ORDER_ID, 0)); + group.setOrderId(JsonUtil.optInt(groupDetails, AuthoringJsonTags.ORDER_ID, 0)); return group; } - private void createRandomGrouping(RandomGrouping randomGrouping, JSONObject groupingDetails) throws JSONException { + private void createRandomGrouping(RandomGrouping randomGrouping, ObjectNode groupingDetails) { // the two settings are mutually exclusive. Authoring takes care of this, // but we'll code it here too just to make sure. - Integer numLearnersPerGroup = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); + Integer numLearnersPerGroup = JsonUtil.optInt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); if ((numLearnersPerGroup != null) && (numLearnersPerGroup.intValue() > 0)) { randomGrouping.setLearnersPerGroup(numLearnersPerGroup); randomGrouping.setNumberOfGroups(null); } else { - Integer numGroups = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); + Integer numGroups = JsonUtil.optInt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); if ((numGroups != null) && (numGroups.intValue() > 0)) { randomGrouping.setNumberOfGroups(numGroups); } else { @@ -731,21 +729,19 @@ } } - private void createChosenGrouping(ChosenGrouping chosenGrouping, JSONObject groupingDetails) { + private void createChosenGrouping(ChosenGrouping chosenGrouping, ObjectNode groupingDetails) { // no extra properties as yet } - private void parseActivities(JSONArray activitiesList) throws ObjectExtractorException, JSONException { - + private void parseActivities(ArrayNode activitiesList) throws ObjectExtractorException { if (activitiesList != null) { - for (int activityIndex = 0; activityIndex < activitiesList.length(); activityIndex++) { - JSONObject activityDetails = activitiesList.getJSONObject(activityIndex); - Activity activity = extractActivityObject(activityDetails); + for (JsonNode activityDetails : activitiesList) { + Activity activity = extractActivityObject((ObjectNode) activityDetails); activityDAO.insertOrUpdate(activity); // if its a tool activity, extract evaluation details if (activity.isToolActivity()) { - extractEvaluationObject(activityDetails, (ToolActivity) activity); + extractEvaluationObject((ObjectNode) activityDetails, (ToolActivity) activity); } newActivityMap.put(activity.getActivityUIID(), activity); @@ -768,9 +764,9 @@ learningDesignDAO.insertOrUpdate(learningDesign); } - private void extractEvaluationObject(JSONObject activityDetails, ToolActivity toolActivity) - throws ObjectExtractorException, JSONException { - String toolOutputDefinition = (String) JsonUtil.opt(activityDetails, AuthoringJsonTags.TOOL_OUTPUT_DEFINITION); + private void extractEvaluationObject(ObjectNode activityDetails, ToolActivity toolActivity) + throws ObjectExtractorException { + String toolOutputDefinition = JsonUtil.optString(activityDetails, AuthoringJsonTags.TOOL_OUTPUT_DEFINITION); if (StringUtils.isNotBlank(toolOutputDefinition)) { ActivityEvaluation evaluation = toolActivity.getEvaluation(); if (evaluation == null) { @@ -779,7 +775,7 @@ } evaluation.setToolOutputDefinition(toolOutputDefinition); - String weight = (String) JsonUtil.opt(activityDetails, AuthoringJsonTags.TOOL_OUTPUT_WEIGHT); + String weight = JsonUtil.optString(activityDetails, AuthoringJsonTags.TOOL_OUTPUT_WEIGHT); if (StringUtils.isBlank(weight)) { evaluation.setWeight(null); } else { @@ -793,13 +789,12 @@ activityDAO.update(toolActivity); } - private void parseCompetences(JSONArray competenceList) throws ObjectExtractorException, JSONException { + private void parseCompetences(ArrayNode competenceList) throws ObjectExtractorException { Set existingCompetences = learningDesign.getCompetences(); if (competenceList != null) { - for (int competenceIndex = 0; competenceIndex < competenceList.length(); competenceIndex++) { - JSONObject competeneJSON = competenceList.getJSONObject(competenceIndex); - String title = competeneJSON.getString(AuthoringJsonTags.TITLE); - String description = competeneJSON.getString(AuthoringJsonTags.DESCRIPTION); + for (JsonNode competenceJSON : competenceList) { + String title = JsonUtil.optString(competenceJSON, AuthoringJsonTags.TITLE); + String description = JsonUtil.optString(competenceJSON, AuthoringJsonTags.DESCRIPTION); if (getComptenceFromSet(existingCompetences, title) != null) { Competence updateCompetence = getComptenceFromSet(existingCompetences, title); @@ -818,12 +813,12 @@ // that dont exist in the new list. Set removeCompetences = new HashSet<>(); if (existingCompetences != null) { - if ((competenceList != null) && (competenceList.length() > 0)) { + if ((competenceList != null) && (competenceList.size() > 0)) { for (Competence existingCompetence : existingCompetences) { boolean remove = true; - for (int competenceIndex = 0; competenceIndex < competenceList.length(); competenceIndex++) { - if (existingCompetence.getTitle().equals( - competenceList.getJSONObject(competenceIndex).getString(AuthoringJsonTags.TITLE))) { + for (JsonNode competenceJSON : competenceList) { + if (existingCompetence.getTitle() + .equals(JsonUtil.optString(competenceJSON, AuthoringJsonTags.TITLE))) { remove = false; break; } @@ -842,7 +837,7 @@ } } - private void parseAnnotations(JSONArray annotationList) throws ObjectExtractorException, JSONException { + private void parseAnnotations(ArrayNode annotationList) throws ObjectExtractorException { if (annotationList == null) { return; } @@ -854,14 +849,13 @@ } Set updatedAnnotations = new HashSet<>(); - for (int annotationIndex = 0; annotationIndex < annotationList.length(); annotationIndex++) { - JSONObject annotationJSON = annotationList.getJSONObject(annotationIndex); + for (JsonNode annotationJSON : annotationList) { boolean found = false; LearningDesignAnnotation annotation = null; for (LearningDesignAnnotation existingAnnotation : existingAnnotations) { if (existingAnnotation.getAnnotationUIID() - .equals(annotationJSON.getInt(AuthoringJsonTags.ANNOTATION_UIID))) { + .equals(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.ANNOTATION_UIID))) { annotation = existingAnnotation; found = true; break; @@ -872,14 +866,14 @@ annotation = new LearningDesignAnnotation(); } annotation.setLearningDesignId(learningDesign.getLearningDesignId()); - annotation.setAnnotationUIID(annotationJSON.getInt(AuthoringJsonTags.ANNOTATION_UIID)); - annotation.setTitle((String) JsonUtil.opt(annotationJSON, AuthoringJsonTags.TITLE)); - annotation.setXcoord((Integer) JsonUtil.opt(annotationJSON, AuthoringJsonTags.XCOORD)); - annotation.setYcoord((Integer) JsonUtil.opt(annotationJSON, AuthoringJsonTags.YCOORD)); - annotation.setEndXcoord((Integer) JsonUtil.opt(annotationJSON, AuthoringJsonTags.END_XCOORD)); - annotation.setEndYcoord((Integer) JsonUtil.opt(annotationJSON, AuthoringJsonTags.END_YCOORD)); - annotation.setColor((String) JsonUtil.opt(annotationJSON, AuthoringJsonTags.COLOR)); - String size = (String) JsonUtil.opt(annotationJSON, AuthoringJsonTags.SIZE); + annotation.setAnnotationUIID(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.ANNOTATION_UIID)); + annotation.setTitle(JsonUtil.optString(annotationJSON, AuthoringJsonTags.TITLE)); + annotation.setXcoord(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.XCOORD)); + annotation.setYcoord(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.YCOORD)); + annotation.setEndXcoord(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.END_XCOORD)); + annotation.setEndYcoord(JsonUtil.optInt(annotationJSON, AuthoringJsonTags.END_YCOORD)); + annotation.setColor(JsonUtil.optString(annotationJSON, AuthoringJsonTags.COLOR)); + String size = JsonUtil.optString(annotationJSON, AuthoringJsonTags.SIZE); if (size != null) { annotation.setSize(Short.valueOf(size)); } @@ -909,17 +903,15 @@ return null; } - private void parseActivitiesToMatchUpParentandInputActivities(JSONArray activitiesList) - throws ObjectExtractorException, JSONException { + private void parseActivitiesToMatchUpParentandInputActivities(ArrayNode activitiesList) + throws ObjectExtractorException { if (activitiesList != null) { - for (int activityIndex = 0; activityIndex < activitiesList.length(); activityIndex++) { - JSONObject activityDetails = activitiesList.getJSONObject(activityIndex); - - Integer activityUUID = activityDetails.getInt(AuthoringJsonTags.ACTIVITY_UIID); + for (JsonNode activityDetails : activitiesList) { + Integer activityUUID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.ACTIVITY_UIID); Activity existingActivity = newActivityMap.get(activityUUID); // match up activity to parent based on UIID - Integer parentUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.PARENT_UIID); + Integer parentUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.PARENT_UIID); if (parentUIID != null) { Activity parentActivity = newActivityMap.get(parentUIID); @@ -945,7 +937,7 @@ // match up activity to input activities based on UIID. At // present there will be only one input activity existingActivity.getInputActivities().clear(); - Integer inputActivityUIID = (Integer) JsonUtil.opt(activityDetails, + Integer inputActivityUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.INPUT_TOOL_ACTIVITY_UIID); if (inputActivityUIID != null) { Activity inputActivity = newActivityMap.get(inputActivityUIID); @@ -962,14 +954,13 @@ } } - private void parseTransitions(JSONArray transitionsList) throws JSONException { + private void parseTransitions(ArrayNode transitionsList) { HashMap newMap = new HashMap<>(); if (transitionsList != null) { - for (int transitionIndex = 0; transitionIndex < transitionsList.length(); transitionIndex++) { - JSONObject transitionDetails = transitionsList.getJSONObject(transitionIndex); - Transition transition = extractTransitionObject(transitionDetails); + for (JsonNode transitionDetails : transitionsList) { + Transition transition = extractTransitionObject((ObjectNode) transitionDetails); // Check if transition actually exists. extractTransitionObject // returns null // if neither the to/from activity exists. @@ -1004,11 +995,11 @@ } - public Activity extractActivityObject(JSONObject activityDetails) throws ObjectExtractorException, JSONException { + public Activity extractActivityObject(ObjectNode activityDetails) throws ObjectExtractorException { // it is assumed that the activityUUID will always be sent by Authoring - Integer activityUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_UIID); - Integer activityTypeID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_TYPE_ID); + Integer activityUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.ACTIVITY_UIID); + Integer activityTypeID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.ACTIVITY_TYPE_ID); Activity activity = null; // get the activity with the particular activity uuid, if null, then new @@ -1027,13 +1018,13 @@ activity.setActivityTypeId(activityTypeID); activity.setActivityUIID(activityUIID); - activity.setDescription((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.DESCRIPTION)); - activity.setTitle((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.ACTIVITY_TITLE)); + activity.setDescription(JsonUtil.optString(activityDetails, AuthoringJsonTags.DESCRIPTION)); + activity.setTitle(JsonUtil.optString(activityDetails, AuthoringJsonTags.ACTIVITY_TITLE)); - activity.setXcoord(getCoord(activityDetails, AuthoringJsonTags.XCOORD)); - activity.setYcoord(getCoord(activityDetails, AuthoringJsonTags.YCOORD)); + activity.setXcoord(JsonUtil.optInt(activityDetails, AuthoringJsonTags.XCOORD, ObjectExtractor.DEFAULT_COORD)); + activity.setYcoord(JsonUtil.optInt(activityDetails, AuthoringJsonTags.YCOORD, ObjectExtractor.DEFAULT_COORD)); - Integer groupingUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.GROUPING_UIID); + Integer groupingUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.GROUPING_UIID); if (groupingUIID == null) { clearGrouping(activity); @@ -1049,7 +1040,7 @@ } - activity.setOrderId((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.ORDER_ID)); + activity.setOrderId(JsonUtil.optInt(activityDetails, AuthoringJsonTags.ORDER_ID)); activity.setLearningDesign(learningDesign); @@ -1065,22 +1056,15 @@ activity.setCreateDateTime(modificationDate); } - 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(JsonUtil.opt(activityDetails, AuthoringJsonTags.STOP_AFTER_ACTIVITY, false)); + activity.setActivityCategoryID(JsonUtil.optInt(activityDetails, AuthoringJsonTags.ACTIVITY_CATEGORY_ID)); + activity.setLibraryActivityUiImage(JsonUtil.optString(activityDetails, AuthoringJsonTags.LIBRARY_IMAGE)); + activity.setGroupingSupportType(JsonUtil.optInt(activityDetails, AuthoringJsonTags.GROUPING_SUPPORT_TYPE)); + activity.setStopAfterActivity( + JsonUtil.optBoolean(activityDetails, AuthoringJsonTags.STOP_AFTER_ACTIVITY, false)); return activity; } - private Integer getCoord(JSONObject details, String tag) throws JSONException { - // the coordinate can be Integer or Double in JSON, need to be ready for any - Number number = (Number) JsonUtil.opt(details, tag); - Integer coord = number == null ? null : number.intValue(); - return (coord == null) || (coord >= 0) ? coord : ObjectExtractor.DEFAULT_COORD; - } - private void clearGrouping(Activity activity) { activity.setGrouping(null); activity.setGroupingUIID(null); @@ -1093,8 +1077,7 @@ activity.setApplyGrouping(true); } - private void processActivityType(Activity activity, JSONObject activityDetails) - throws ObjectExtractorException, JSONException { + private void processActivityType(Activity activity, ObjectNode activityDetails) throws ObjectExtractorException { if (activity.isGroupingActivity()) { buildGroupingActivity((GroupingActivity) activity, activityDetails); } else if (activity.isToolActivity()) { @@ -1106,17 +1089,16 @@ } } - private void buildComplexActivity(ComplexActivity activity, JSONObject activityDetails) - throws ObjectExtractorException, JSONException { + private void buildComplexActivity(ComplexActivity activity, ObjectNode activityDetails) + throws 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.setDefaultActivity(null); - Integer defaultActivityMapUIID = (Integer) JsonUtil.opt(activityDetails, - AuthoringJsonTags.DEFAULT_ACTIVITY_UIID); + Integer defaultActivityMapUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.DEFAULT_ACTIVITY_UIID); if (defaultActivityMapUIID != null) { defaultActivityMap.put(defaultActivityMapUIID, activity); } @@ -1135,17 +1117,16 @@ } } - private void buildFloatingActivity(FloatingActivity floatingActivity, JSONObject activityDetails) - throws ObjectExtractorException, JSONException { - floatingActivity - .setMaxNumberOfActivities((Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.MAX_ACTIVITIES)); + private void buildFloatingActivity(FloatingActivity floatingActivity, ObjectNode activityDetails) + throws ObjectExtractorException { + floatingActivity.setMaxNumberOfActivities(JsonUtil.optInt(activityDetails, AuthoringJsonTags.MAX_ACTIVITIES)); SystemTool systemTool = getSystemTool(SystemTool.FLOATING_ACTIVITIES); floatingActivity.setSystemTool(systemTool); } - private void buildBranchingActivity(BranchingActivity branchingActivity, JSONObject activityDetails) - throws ObjectExtractorException, JSONException { + private void buildBranchingActivity(BranchingActivity branchingActivity, ObjectNode activityDetails) + throws ObjectExtractorException { if (branchingActivity.isChosenBranchingActivity()) { branchingActivity.setSystemTool(getSystemTool(SystemTool.TEACHER_CHOSEN_BRANCHING)); } else if (branchingActivity.isGroupBranchingActivity()) { @@ -1154,18 +1135,22 @@ branchingActivity.setSystemTool(getSystemTool(SystemTool.TOOL_BASED_BRANCHING)); } - branchingActivity.setStartXcoord(getCoord(activityDetails, AuthoringJsonTags.START_XCOORD)); - branchingActivity.setStartYcoord(getCoord(activityDetails, AuthoringJsonTags.START_YCOORD)); - branchingActivity.setEndXcoord(getCoord(activityDetails, AuthoringJsonTags.END_XCOORD)); - branchingActivity.setEndYcoord(getCoord(activityDetails, AuthoringJsonTags.END_YCOORD)); + branchingActivity.setStartXcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.START_XCOORD, ObjectExtractor.DEFAULT_COORD)); + branchingActivity.setStartYcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.START_YCOORD, ObjectExtractor.DEFAULT_COORD)); + branchingActivity.setEndXcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.END_XCOORD, ObjectExtractor.DEFAULT_COORD)); + branchingActivity.setEndYcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.END_YCOORD, ObjectExtractor.DEFAULT_COORD)); } - private void buildGroupingActivity(GroupingActivity groupingActivity, JSONObject activityDetails) - throws ObjectExtractorException, JSONException { + private void buildGroupingActivity(GroupingActivity groupingActivity, ObjectNode activityDetails) + throws ObjectExtractorException { /** * read the createGroupingUUID, get the Grouping Object, and set CreateGrouping to that object */ - Integer createGroupingUIID = (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.CREATE_GROUPING_UIID); + Integer createGroupingUIID = JsonUtil.optInt(activityDetails, AuthoringJsonTags.CREATE_GROUPING_UIID); Grouping grouping = groupings.get(createGroupingUIID); if (grouping != null) { groupingActivity.setCreateGrouping(grouping); @@ -1176,22 +1161,24 @@ groupingActivity.setSystemTool(systemTool); } - 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)); + private void buildOptionsActivity(OptionsActivity optionsActivity, ObjectNode activityDetails) { + optionsActivity.setMaxNumberOfOptions(JsonUtil.optInt(activityDetails, AuthoringJsonTags.MAX_OPTIONS)); + optionsActivity.setMinNumberOfOptions(JsonUtil.optInt(activityDetails, AuthoringJsonTags.MIN_OPTIONS)); optionsActivity - .setOptionsInstructions((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.OPTIONS_INSTRUCTIONS)); + .setOptionsInstructions(JsonUtil.optString(activityDetails, AuthoringJsonTags.OPTIONS_INSTRUCTIONS)); } private void buildOptionsWithSequencesActivity(OptionsWithSequencesActivity optionsActivity, - JSONObject activityDetails) throws JSONException { + ObjectNode activityDetails) { buildOptionsActivity(optionsActivity, activityDetails); - - optionsActivity.setStartXcoord(getCoord(activityDetails, AuthoringJsonTags.START_XCOORD)); - optionsActivity.setStartYcoord(getCoord(activityDetails, AuthoringJsonTags.START_YCOORD)); - optionsActivity.setEndXcoord(getCoord(activityDetails, AuthoringJsonTags.END_XCOORD)); - optionsActivity.setEndYcoord(getCoord(activityDetails, AuthoringJsonTags.END_YCOORD)); + optionsActivity.setStartXcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.START_XCOORD, ObjectExtractor.DEFAULT_COORD)); + optionsActivity.setStartYcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.START_YCOORD, ObjectExtractor.DEFAULT_COORD)); + optionsActivity.setEndXcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.END_XCOORD, ObjectExtractor.DEFAULT_COORD)); + optionsActivity.setEndYcoord( + JsonUtil.optInt(activityDetails, AuthoringJsonTags.END_YCOORD, ObjectExtractor.DEFAULT_COORD)); } private void buildParallelActivity(ParallelActivity activity) { @@ -1201,7 +1188,7 @@ activity.setSystemTool(getSystemTool(SystemTool.SEQUENCE)); } - private void buildToolActivity(ToolActivity toolActivity, JSONObject activityDetails) throws JSONException { + private void buildToolActivity(ToolActivity toolActivity, ObjectNode activityDetails) { Tool tool = toolDAO.getToolByID(JsonUtil.optLong(activityDetails, AuthoringJsonTags.TOOL_ID)); toolActivity.setTool(tool); @@ -1218,7 +1205,7 @@ toolActivity.setToolContentId(toolContentId); } - private void buildGateActivity(Object activity, JSONObject activityDetails) throws JSONException { + private void buildGateActivity(Object activity, ObjectNode activityDetails) { if (activity instanceof SynchGateActivity) { buildSynchGateActivity((SynchGateActivity) activity); } else if (activity instanceof PermissionGateActivity) { @@ -1231,9 +1218,8 @@ buildScheduleGateActivity((ScheduleGateActivity) activity, activityDetails); } GateActivity gateActivity = (GateActivity) activity; - gateActivity.setGateActivityLevelId( - (Integer) JsonUtil.opt(activityDetails, AuthoringJsonTags.GATE_ACTIVITY_LEVEL_ID)); - gateActivity.setGateOpen((Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.GATE_OPEN)); + gateActivity.setGateActivityLevelId(JsonUtil.optInt(activityDetails, AuthoringJsonTags.GATE_ACTIVITY_LEVEL_ID)); + gateActivity.setGateOpen(JsonUtil.optBoolean(activityDetails, AuthoringJsonTags.GATE_OPEN)); } @@ -1249,17 +1235,16 @@ activity.setSystemTool(getSystemTool(SystemTool.SYSTEM_GATE)); } - private void buildScheduleGateActivity(ScheduleGateActivity activity, JSONObject activityDetails) - throws JSONException { + private void buildScheduleGateActivity(ScheduleGateActivity activity, ObjectNode activityDetails) { activity.setGateStartTimeOffset(JsonUtil.optLong(activityDetails, AuthoringJsonTags.GATE_START_OFFSET)); activity.setGateEndTimeOffset(JsonUtil.optLong(activityDetails, AuthoringJsonTags.GATE_END_OFFSET)); activity.setGateActivityCompletionBased( - (Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.GATE_ACTIVITY_COMPLETION_BASED)); + JsonUtil.optBoolean(activityDetails, AuthoringJsonTags.GATE_ACTIVITY_COMPLETION_BASED)); SystemTool systemTool = getSystemTool(SystemTool.SCHEDULE_GATE); activity.setSystemTool(systemTool); } - private void createLessonClass(LessonClass lessonClass, JSONObject groupingDetails) throws JSONException { + private void createLessonClass(LessonClass lessonClass, ObjectNode groupingDetails) { Long groupId = JsonUtil.optLong(groupingDetails, AuthoringJsonTags.STAFF_GROUP_ID); if (groupId != null) { Group group = groupDAO.getGroupById(groupId); @@ -1269,13 +1254,12 @@ } } - private Transition extractTransitionObject(JSONObject transitionDetails) throws JSONException { + private Transition extractTransitionObject(ObjectNode transitionDetails) { + Integer transitionUUID = JsonUtil.optInt(transitionDetails, AuthoringJsonTags.TRANSITION_UIID); + Integer toUIID = JsonUtil.optInt(transitionDetails, AuthoringJsonTags.TO_ACTIVITY_UIID); + Integer fromUIID = JsonUtil.optInt(transitionDetails, AuthoringJsonTags.FROM_ACTIVITY_UIID); + Integer transitionType = JsonUtil.optInt(transitionDetails, AuthoringJsonTags.TRANSITION_TYPE); - Integer transitionUUID = transitionDetails.getInt(AuthoringJsonTags.TRANSITION_UIID); - Integer toUIID = transitionDetails.getInt(AuthoringJsonTags.TO_ACTIVITY_UIID); - Integer fromUIID = transitionDetails.getInt(AuthoringJsonTags.FROM_ACTIVITY_UIID); - Integer transitionType = transitionDetails.getInt(AuthoringJsonTags.TRANSITION_TYPE); - Transition transition = null; Transition existingTransition = findTransition(transitionUUID, toUIID, fromUIID, transitionType); @@ -1321,8 +1305,8 @@ transition.setFromUIID(null); } - transition.setDescription((String) JsonUtil.opt(transitionDetails, AuthoringJsonTags.DESCRIPTION)); - transition.setTitle((String) JsonUtil.opt(transitionDetails, AuthoringJsonTags.TITLE)); + transition.setDescription(JsonUtil.optString(transitionDetails, AuthoringJsonTags.DESCRIPTION)); + transition.setTitle(JsonUtil.optString(transitionDetails, AuthoringJsonTags.TITLE)); // Set creation date based on the server timezone, not the client. if (transition.getCreateDateTime() == null) { @@ -1392,10 +1376,10 @@ return mode; } - private void parseBranchMappings(JSONArray branchMappingsList) throws JSONException, ObjectExtractorException { + private void parseBranchMappings(ArrayNode branchMappingsList) throws ObjectExtractorException { if (branchMappingsList != null) { - for (int branchMappingIndex = 0; branchMappingIndex < branchMappingsList.length(); branchMappingIndex++) { - extractBranchActivityEntry(branchMappingsList.getJSONObject(branchMappingIndex)); + for (JsonNode branchMappingJSON : branchMappingsList) { + extractBranchActivityEntry((ObjectNode) branchMappingJSON); } } @@ -1423,20 +1407,19 @@ } } - private BranchActivityEntry extractBranchActivityEntry(JSONObject details) - throws JSONException, ObjectExtractorException { + private BranchActivityEntry extractBranchActivityEntry(ObjectNode details) throws ObjectExtractorException { Long entryId = JsonUtil.optLong(details, AuthoringJsonTags.BRANCH_ACTIVITY_ENTRY_ID); - Integer entryUIID = details.getInt(AuthoringJsonTags.BRANCH_ACTIVITY_ENTRY_UIID); + Integer entryUIID = JsonUtil.optInt(details, AuthoringJsonTags.BRANCH_ACTIVITY_ENTRY_UIID); - Integer sequenceActivityUIID = (Integer) JsonUtil.opt(details, AuthoringJsonTags.BRANCH_SEQUENCE_ACTIVITY_UIID); - Boolean gateOpenWhenConditionMet = (Boolean) JsonUtil.opt(details, + Integer sequenceActivityUIID = JsonUtil.optInt(details, AuthoringJsonTags.BRANCH_SEQUENCE_ACTIVITY_UIID); + Boolean gateOpenWhenConditionMet = JsonUtil.optBoolean(details, AuthoringJsonTags.BRANCH_GATE_OPENS_WHEN_CONDITION_MET); Integer branchingActivityUIID = null; if (gateOpenWhenConditionMet != null) { - branchingActivityUIID = details.getInt(AuthoringJsonTags.BRANCH_GATE_ACTIVITY_UIID); + branchingActivityUIID = JsonUtil.optInt(details, AuthoringJsonTags.BRANCH_GATE_ACTIVITY_UIID); } else { - branchingActivityUIID = details.getInt(AuthoringJsonTags.BRANCH_ACTIVITY_UIID); + branchingActivityUIID = JsonUtil.optInt(details, AuthoringJsonTags.BRANCH_ACTIVITY_UIID); } Activity branchingActivity = newActivityMap.get(branchingActivityUIID); @@ -1507,9 +1490,10 @@ // (which is used for doing deletions later). oldbranchActivityEntryList.remove(entry); - BranchCondition condition = extractCondition(details.optJSONObject(AuthoringJsonTags.BRANCH_CONDITION), entry); + BranchCondition condition = extractCondition(JsonUtil.optObject(details, AuthoringJsonTags.BRANCH_CONDITION), + entry); - Integer groupUIID = (Integer) JsonUtil.opt(details, AuthoringJsonTags.GROUP_UIID); + Integer groupUIID = JsonUtil.optInt(details, AuthoringJsonTags.GROUP_UIID); Group group = null; if (groupUIID != null) { group = groups.get(groupUIID); @@ -1574,8 +1558,7 @@ return entry; } - private BranchCondition extractCondition(JSONObject conditionDetails, BranchActivityEntry entry) - throws JSONException { + private BranchCondition extractCondition(ObjectNode conditionDetails, BranchActivityEntry entry) { BranchCondition condition = null; @@ -1593,13 +1576,14 @@ // automatically via the cascade } - Integer conditionUIID = conditionDetails.getInt(AuthoringJsonTags.CONDITION_UIID); - String conditionType = conditionDetails.getString(AuthoringJsonTags.CONDITION_TYPE); + Integer conditionUIID = JsonUtil.optInt(conditionDetails, AuthoringJsonTags.CONDITION_UIID); + String conditionType = JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_TYPE); if (BranchCondition.OUTPUT_TYPE_COMPLEX.equals(conditionType) || BranchCondition.OUTPUT_TYPE_STRING.equals(conditionType)) { // This is different than "conditionID" !!! - Long newConditionID = condition == null ? conditionDetails.getLong(AuthoringJsonTags.CONDITION_ID) + Long newConditionID = condition == null + ? JsonUtil.optLong(conditionDetails, AuthoringJsonTags.CONDITION_ID) : condition.getConditionId(); // we need to get the proper subclass, since the one provided by branch entry is not valid BranchCondition originalCondition = branchActivityEntryDAO.getConditionByID(newConditionID); @@ -1615,24 +1599,24 @@ } } else if (condition == null) { condition = new BranchCondition(null, conditionUIID, - conditionDetails.getInt(AuthoringJsonTags.ORDER_ID), - conditionDetails.getString(AuthoringJsonTags.CONDITION_NAME), - conditionDetails.getString(AuthoringJsonTags.CONDITION_DISPLAY_NAME), - conditionDetails.getString(AuthoringJsonTags.CONDITION_TYPE), - (String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_START_VALUE), - (String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_END_VALUE), - (String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_EXACT_MATCH_VALUE)); + JsonUtil.optInt(conditionDetails, AuthoringJsonTags.ORDER_ID), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_NAME), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_DISPLAY_NAME), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_TYPE), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_START_VALUE), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_END_VALUE), + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_EXACT_MATCH_VALUE)); } else { condition.setConditionUIID(conditionUIID); - condition.setDisplayName(conditionDetails.getString(AuthoringJsonTags.CONDITION_DISPLAY_NAME)); - condition.setEndValue((String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_END_VALUE)); + condition + .setDisplayName(JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_DISPLAY_NAME)); + condition.setEndValue(JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_END_VALUE)); condition.setExactMatchValue( - (String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_EXACT_MATCH_VALUE)); - condition.setName(conditionDetails.getString(AuthoringJsonTags.CONDITION_NAME)); - condition.setOrderId(conditionDetails.getInt(AuthoringJsonTags.ORDER_ID)); - condition.setStartValue( - (String) JsonUtil.opt(conditionDetails, AuthoringJsonTags.CONDITION_START_VALUE)); - condition.setType(conditionDetails.getString(AuthoringJsonTags.CONDITION_TYPE)); + JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_EXACT_MATCH_VALUE)); + condition.setName(JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_NAME)); + condition.setOrderId(JsonUtil.optInt(conditionDetails, AuthoringJsonTags.ORDER_ID)); + condition.setStartValue(JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_START_VALUE)); + condition.setType(JsonUtil.optString(conditionDetails, AuthoringJsonTags.CONDITION_TYPE)); } } return condition; @@ -1651,16 +1635,15 @@ return tool; } - private void createLearnerChoiceGrouping(LearnerChoiceGrouping learnerChoiceGrouping, JSONObject groupingDetails) - throws JSONException { - Integer numLearnersPerGroup = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); + private void createLearnerChoiceGrouping(LearnerChoiceGrouping learnerChoiceGrouping, ObjectNode groupingDetails) { + Integer numLearnersPerGroup = JsonUtil.optInt(groupingDetails, AuthoringJsonTags.LEARNERS_PER_GROUP); if ((numLearnersPerGroup != null) && (numLearnersPerGroup.intValue() > 0)) { learnerChoiceGrouping.setLearnersPerGroup(numLearnersPerGroup); learnerChoiceGrouping.setNumberOfGroups(null); learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(null); } else { - Integer numGroups = (Integer) JsonUtil.opt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); + Integer numGroups = JsonUtil.optInt(groupingDetails, AuthoringJsonTags.NUMBER_OF_GROUPS); if ((numGroups != null) && (numGroups.intValue() > 0)) { learnerChoiceGrouping.setNumberOfGroups(numGroups); @@ -1669,14 +1652,14 @@ } learnerChoiceGrouping.setLearnersPerGroup(null); - Boolean equalNumberOfLearnersPerGroup = (Boolean) JsonUtil.opt(groupingDetails, + Boolean equalNumberOfLearnersPerGroup = JsonUtil.optBoolean(groupingDetails, AuthoringJsonTags.EQUAL_NUMBER_OF_LEARNERS_PER_GROUP); if (equalNumberOfLearnersPerGroup != null) { learnerChoiceGrouping.setEqualNumberOfLearnersPerGroup(equalNumberOfLearnersPerGroup); } } learnerChoiceGrouping.setViewStudentsBeforeSelection( - (Boolean) JsonUtil.opt(groupingDetails, AuthoringJsonTags.VIEW_STUDENTS_BEFORE_SELECTION)); + JsonUtil.optBoolean(groupingDetails, AuthoringJsonTags.VIEW_STUDENTS_BEFORE_SELECTION)); } private void buildConditionGateActivity(ConditionGateActivity activity) { Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java =================================================================== diff -u -r9cadc392ac9854c077a9da549309831e2c3ae7cc -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 9cadc392ac9854c077a9da549309831e2c3ae7cc) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -44,8 +44,6 @@ import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.authoring.IObjectExtractor; import org.lamsfoundation.lams.authoring.ObjectExtractorException; import org.lamsfoundation.lams.dao.IBaseDAO; @@ -108,6 +106,7 @@ import org.lamsfoundation.lams.usermanagement.exception.WorkspaceFolderException; import org.lamsfoundation.lams.util.Configuration; import org.lamsfoundation.lams.util.ConfigurationKeys; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.MessageService; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; @@ -116,6 +115,8 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Manpreet Minhas */ @@ -165,7 +166,7 @@ protected IWorkspaceManagementService workspaceManagementService; protected ILogEventService logEventService; - + protected IGradebookService gradebookService; protected ToolContentIDGenerator contentIDGenerator; @@ -343,7 +344,7 @@ } public void setGradebookService(IGradebookService gradebookService) { - this.gradebookService = gradebookService; + this.gradebookService = gradebookService; } public void setWorkspaceManagementService(IWorkspaceManagementService workspaceManagementService) { @@ -508,7 +509,6 @@ } // only the user who is editing the design may unlock it if (design.getEditOverrideUser().equals(user)) { - design.setEditOverrideLock(false); design.setEditOverrideUser(null); @@ -543,7 +543,7 @@ initialiseToolActivityForRuntime(design, lesson); learningDesignDAO.update(design); - + // Always recalculate marks as we can't tell if weightings have been changed/added/removed. // This will override any Gradebook entered *lesson* marks, but will calculate based on // Gradebook entered *activity* marks. @@ -1462,8 +1462,8 @@ } @Override - public LearningDesign saveLearningDesignDetails(JSONObject ldJSON) - throws UserException, JSONException, WorkspaceFolderException, ObjectExtractorException, ParseException { + public LearningDesign saveLearningDesignDetails(ObjectNode ldJSON) + throws UserException, WorkspaceFolderException, ObjectExtractorException, ParseException { User user = null; Integer userID = AuthoringService.getUserId(); if (userID != null) { @@ -1473,15 +1473,15 @@ throw new UserException("UserID missing or user not found."); } - Integer workspaceFolderID = ldJSON.getInt("workspaceFolderID"); + Integer workspaceFolderID = JsonUtil.optInt(ldJSON, "workspaceFolderID"); WorkspaceFolder workspaceFolder = null; boolean authorised = false; if (workspaceFolderID != null) { workspaceFolder = (WorkspaceFolder) baseDAO.find(WorkspaceFolder.class, workspaceFolderID); authorised = workspaceManagementService.isUserAuthorizedToModifyFolderContents(workspaceFolderID, userID); } - Long learningDesignId = ldJSON.optLong(AttributeNames.PARAM_LEARNINGDESIGN_ID); + Long learningDesignId = JsonUtil.optLong(ldJSON, AttributeNames.PARAM_LEARNINGDESIGN_ID); LearningDesign existingLearningDesign = learningDesignId == null ? null : learningDesignDAO.getLearningDesignById(learningDesignId); if (!authorised && (existingLearningDesign != null) @@ -1500,8 +1500,7 @@ if (extractor.getMode().intValue() == 1) { // adding the customCSV to the call if it is present - String customCSV = ldJSON.optString("customCSV"); - + String customCSV = JsonUtil.optString(ldJSON, "customCSV"); copyLearningDesignToolContent(design, design, design.getCopyTypeID(), customCSV); } Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java =================================================================== diff -u -ra949c337adc53b2df9207aa1de6e500281de7c20 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java (.../IAuthoringService.java) (revision a949c337adc53b2df9207aa1de6e500281de7c20) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/IAuthoringService.java (.../IAuthoringService.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -28,8 +28,8 @@ import java.util.List; import java.util.Vector; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; + + import org.lamsfoundation.lams.authoring.ObjectExtractorException; import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.LearningDesign; @@ -48,6 +48,8 @@ import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.MessageService; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Manpreet Minhas */ @@ -152,8 +154,8 @@ boolean createNewLearningDesign, String newDesignName, Integer workspaceFolderID, String customCSV) throws UserException, LearningDesignException, WorkspaceFolderException, IOException; - LearningDesign saveLearningDesignDetails(JSONObject ldJSON) - throws UserException, JSONException, WorkspaceFolderException, ObjectExtractorException, ParseException; + LearningDesign saveLearningDesignDetails(ObjectNode ldJSON) + throws UserException, WorkspaceFolderException, ObjectExtractorException, ParseException; /** * Validate the learning design, updating the valid flag appropriately. Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java =================================================================== diff -u -ra949c337adc53b2df9207aa1de6e500281de7c20 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision a949c337adc53b2df9207aa1de6e500281de7c20) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/AuthoringAction.java (.../AuthoringAction.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -43,9 +43,6 @@ 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.integration.ExtCourseClassMap; @@ -79,22 +76,20 @@ import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.CentralConstants; import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; /** * @author Manpreet Minhas - * - * - * - * */ public class AuthoringAction extends LamsDispatchAction { @@ -123,29 +118,27 @@ } public ActionForward openAuthoring(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, JSONException { + HttpServletResponse response) throws IOException { request.setAttribute(AttributeNames.PARAM_CONTENT_FOLDER_ID, FileUtil.generateUniqueContentFolderID()); request.setAttribute("tools", getLearningDesignService().getToolDTOs(true, true, request.getRemoteUser())); // build list of existing learning library groups List groups = getLearningDesignService().getLearningLibraryGroups(); - JSONArray groupsJSON = new JSONArray(); + ArrayNode groupsJSON = JsonNodeFactory.instance.arrayNode(); for (LearningLibraryGroup group : groups) { - JSONObject groupJSON = new JSONObject(); + ObjectNode groupJSON = JsonNodeFactory.instance.objectNode(); groupJSON.put("name", group.getName()); for (LearningLibrary learningLibrary : group.getLearningLibraries()) { - groupJSON.append("learningLibraries", learningLibrary.getLearningLibraryId()); + groupJSON.withArray("learningLibraries").add(learningLibrary.getLearningLibraryId()); } - groupsJSON.put(groupJSON); + groupsJSON.add(groupJSON); } request.setAttribute("learningLibraryGroups", groupsJSON.toString()); List accessList = getAuthoringService().updateLearningDesignAccessByUser(getUserId()); accessList = accessList.subList(0, Math.min(accessList.size(), AuthoringAction.LEARNING_DESIGN_ACCESS_ENTRIES_LIMIT - 1)); - Gson gson = new GsonBuilder().create(); - request.setAttribute("access", gson.toJson(accessList)); - + request.setAttribute("access", JsonUtil.toString(accessList)); request.setAttribute("licenses", getAuthoringService().getAvailableLicenses()); return mapping.findForward("openAutoring"); @@ -159,23 +152,22 @@ } public ActionForward getToolOutputDefinitions(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, JSONException { + HttpServletResponse response) throws ServletException, IOException { IAuthoringService authoringService = getAuthoringService(); Long toolContentID = WebUtil.readLongParam(request, "toolContentID"); Integer definitionType = ToolOutputDefinition.DATA_OUTPUT_DEFINITION_TYPE_CONDITION; List defnDTOList = authoringService.getToolOutputDefinitions(toolContentID, definitionType); - Gson gson = new GsonBuilder().create(); response.setContentType("application/json;charset=utf-8"); - response.getWriter().write(gson.toJson(defnDTOList)); + response.getWriter().write(JsonUtil.toString(defnDTOList)); return null; } @SuppressWarnings("unchecked") public ActionForward openLearningDesign(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws ServletException, IOException, JSONException { + HttpServletResponse response) throws ServletException, IOException { long learningDesignID = WebUtil.readLongParam(request, AttributeNames.PARAM_LEARNINGDESIGN_ID); LearningDesignDTO learningDesignDTO = getLearningDesignService().getLearningDesignDTO(learningDesignID, getUserLanguage()); @@ -193,14 +185,13 @@ } response.setContentType("application/json;charset=utf-8"); - JSONObject responseJSON = new JSONObject(); - Gson gson = new GsonBuilder().create(); - responseJSON.put("ld", new JSONObject(gson.toJson(learningDesignDTO))); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + responseJSON.set("ld", JsonUtil.readObject(learningDesignDTO)); List accessList = getAuthoringService().updateLearningDesignAccessByUser(userId); accessList = accessList.subList(0, Math.min(accessList.size(), AuthoringAction.LEARNING_DESIGN_ACCESS_ENTRIES_LIMIT - 1)); - responseJSON.put("access", new JSONArray(gson.toJson(accessList))); + responseJSON.set("access", JsonUtil.readArray(accessList)); response.getWriter().write(responseJSON.toString()); return null; @@ -247,7 +238,7 @@ * Creates a copy of default tool content. */ public ActionForward createToolContent(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { IAuthoringService authoringService = getAuthoringService(); Long toolID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_ID); Long toolContentID = WebUtil.readLongParam(request, AttributeNames.PARAM_TOOL_CONTENT_ID, true); @@ -264,7 +255,7 @@ String authorUrl = authoringService.getToolAuthorUrl(toolID, toolContentID, contentFolderID); if (authorUrl != null) { - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); responseJSON.put("authorURL", authorUrl); // return the generated values responseJSON.put(AttributeNames.PARAM_TOOL_CONTENT_ID, toolContentID); @@ -322,11 +313,11 @@ null, false, false, false, false, true, true, false, false, null, null); Organisation organisation = getMonitoringService().getOrganisation(organisationID); - List staffList = new LinkedList(); + List staffList = new LinkedList<>(); staffList.add(user); // add organisation's learners as lesson participants - List learnerList = new LinkedList(); + List learnerList = new LinkedList<>(); Vector learnerVector = getUserManagementService().getUsersFromOrganisationByRole(organisationID, Role.LEARNER, true); learnerList.addAll(learnerVector); @@ -351,23 +342,21 @@ * Stores Learning Desing created in Authoring. */ public ActionForward saveLearningDesign(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws JSONException, UserException, WorkspaceFolderException, IOException, - ObjectExtractorException, ParseException { - JSONObject ldJSON = new JSONObject(request.getParameter("ld")); + HttpServletResponse response) + throws UserException, WorkspaceFolderException, IOException, ObjectExtractorException, ParseException { + ObjectNode ldJSON = JsonUtil.readObject(request.getParameter("ld")); LearningDesign learningDesign = getAuthoringService().saveLearningDesignDetails(ldJSON); - JSONObject responseJSON = new JSONObject(); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); if (learningDesign != null) { Long learningDesignID = learningDesign.getLearningDesignId(); if (learningDesignID != null) { responseJSON.put("learningDesignID", learningDesignID); - Gson gson = new GsonBuilder().create(); Vector validationDTOs = getAuthoringService() .validateLearningDesign(learningDesignID); - String validationJSON = gson.toJson(validationDTOs); - responseJSON.put("validation", new JSONArray(validationJSON)); + responseJSON.set("validation", JsonUtil.readArray(validationDTOs)); } } @@ -386,10 +375,9 @@ List accessList = getAuthoringService().updateLearningDesignAccessByUser(userId); accessList = accessList.subList(0, Math.min(accessList.size(), AuthoringAction.LEARNING_DESIGN_ACCESS_ENTRIES_LIMIT - 1)); - Gson gson = new GsonBuilder().create(); response.setContentType("application/json;charset=utf-8"); - response.getWriter().write(gson.toJson(accessList)); + response.getWriter().write(JsonUtil.toString(accessList)); return null; } @@ -417,16 +405,16 @@ public ActionForward saveActivityCoordinates(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException { try { - JSONObject activityJSON = new JSONObject(request.getParameter("activity")); - Activity activity = getMonitoringService().getActivityById(activityJSON.getLong("activityID")); - activity.setXcoord(activityJSON.optInt("xCoord")); - activity.setYcoord(activityJSON.optInt("yCoord")); + ObjectNode activityJSON = JsonUtil.readObject(request.getParameter("activity")); + Activity activity = getMonitoringService().getActivityById(JsonUtil.optLong(activityJSON, "activityID")); + activity.setXcoord(JsonUtil.optInt(activityJSON, "xCoord")); + activity.setYcoord(JsonUtil.optInt(activityJSON, "yCoord")); if (activity.isBranchingActivity()) { BranchingActivity branchingActivity = (BranchingActivity) activity; - branchingActivity.setStartXcoord(activityJSON.getInt("startXCoord")); - branchingActivity.setEndXcoord(activityJSON.getInt("endXCoord")); - branchingActivity.setStartYcoord(activityJSON.getInt("startYCoord")); - branchingActivity.setEndYcoord(activityJSON.getInt("endYCoord")); + branchingActivity.setStartXcoord(JsonUtil.optInt(activityJSON, "startXCoord")); + branchingActivity.setEndXcoord(JsonUtil.optInt(activityJSON, "endXCoord")); + branchingActivity.setStartYcoord(JsonUtil.optInt(activityJSON, "startYCoord")); + branchingActivity.setEndYcoord(JsonUtil.optInt(activityJSON, "endYCoord")); } getUserManagementService().save(activity); } catch (Exception e) { Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java =================================================================== diff -u -r64e6623bc68b11257c7f5d71f3953154f80b6fde -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java (.../AuthoringActivityDTO.java) (revision 64e6623bc68b11257c7f5d71f3953154f80b6fde) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java (.../AuthoringActivityDTO.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -271,6 +271,9 @@ /******************************************************************************************************************* * Constructors ******************************************************************************************************************/ + public AuthoringActivityDTO() { + } + public AuthoringActivityDTO(Activity activity, ArrayList branchMappings, String languageCode) { activityID = activity.getActivityId(); Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java =================================================================== diff -u -r64e6623bc68b11257c7f5d71f3953154f80b6fde -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision 64e6623bc68b11257c7f5d71f3953154f80b6fde) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -141,9 +141,10 @@ import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; -import com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider; + import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.xml.StaxDriver; import com.thoughtworks.xstream.security.AnyTypePermission; /** @@ -477,7 +478,7 @@ } // exporting XML - XStream designXml = new XStream(new SunUnsafeReflectionProvider()); + XStream designXml = new XStream(new StaxDriver()); designXml.addPermission(AnyTypePermission.ANY); designXml.toXML(ldDto, ldFile); ldFile.close(); @@ -548,7 +549,7 @@ Writer toolFile = new OutputStreamWriter(new FileOutputStream(toolFileName), "UTF-8"); // serialize tool xml into local file. - XStream toolXml = new XStream(new SunUnsafeReflectionProvider()); + XStream toolXml = new XStream(new StaxDriver()); toolXml.addPermission(AnyTypePermission.ANY); FileConverter fileConverter = null; if (!fileHandleClassList.isEmpty()) { @@ -903,7 +904,7 @@ String toVersion) throws ImportToolContentException { Object toolPOJO = null; // change xml to Tool POJO - XStream toolXml = new XStream(new SunUnsafeReflectionProvider()); + XStream toolXml = new XStream(new StaxDriver()); toolXml.addPermission(AnyTypePermission.ANY); FileConverter fileConverter = null; if (!fileHandleClassList.isEmpty()) { Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookMonitoringAction.java =================================================================== diff -u -ra949c337adc53b2df9207aa1de6e500281de7c20 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookMonitoringAction.java (.../GradebookMonitoringAction.java) (revision a949c337adc53b2df9207aa1de6e500281de7c20) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/web/action/GradebookMonitoringAction.java (.../GradebookMonitoringAction.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.gradebook.web.action; import java.io.IOException; @@ -39,8 +38,6 @@ import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; -import org.apache.tomcat.util.json.JSONException; -import org.apache.tomcat.util.json.JSONObject; import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.gradebook.util.GBGridView; import org.lamsfoundation.lams.gradebook.util.GradebookConstants; @@ -58,13 +55,17 @@ import org.lamsfoundation.lams.util.ExcelCell; import org.lamsfoundation.lams.util.ExcelUtil; import org.lamsfoundation.lams.util.FileUtil; +import org.lamsfoundation.lams.util.JsonUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; import org.lamsfoundation.lams.web.session.SessionManager; import org.lamsfoundation.lams.web.util.AttributeNames; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author lfoxton * @@ -104,7 +105,7 @@ LessonDetailsDTO lessonDetatilsDTO = lesson.getLessonDetails(); request.setAttribute("lessonDetails", lessonDetatilsDTO); request.setAttribute("marksReleased", marksReleased); - + List weights = getGradebookService().getWeights(lesson.getLearningDesign()); if ( weights.size() > 0 ) { request.setAttribute("weights", weights); @@ -381,7 +382,7 @@ response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the organisation"); return null; } - + boolean simplified = WebUtil.readBooleanParam(request, "simplified", false); Organisation organisation = (Organisation) getUserService().findById(Organisation.class, organisationID); @@ -411,12 +412,12 @@ return null; } - + /** * Get the raw marks for display in a histogram. */ public ActionForward getMarkChartData(ActionMapping mapping, ActionForm form, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException, JSONException { + HttpServletResponse response) throws IOException, ServletException { Long lessonID = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); if (!getSecurityService().isLessonMonitor(lessonID, getUser().getUserID(), @@ -426,13 +427,14 @@ } List results = getGradebookService().getMarksArray(lessonID); - - JSONObject responseJSON = new JSONObject(); - if ( results != null ) - responseJSON.put("data", results); - else - responseJSON.put("data", new Float[0]); + ObjectNode responseJSON = JsonNodeFactory.instance.objectNode(); + if (results != null) { + responseJSON.set("data", JsonUtil.readArray(results)); + } else { + responseJSON.set("data", JsonUtil.readArray(new Float[0])); + } + response.setContentType("application/json;charset=utf-8"); response.getWriter().write(responseJSON.toString()); return null; @@ -444,11 +446,6 @@ return (UserDTO) ss.getAttribute(AttributeNames.USER); } - private ActionForward displayMessage(ActionMapping mapping, HttpServletRequest req, String messageKey) { - req.setAttribute("messageKey", messageKey); - return mapping.findForward("message"); - } - private IUserManagementService getUserService() { if (GradebookMonitoringAction.userService == null) { WebApplicationContext ctx = WebApplicationContextUtils Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -rba995699c252120c1dfcbf13e0043993a804abe6 -rba813ea0cf758315d5d6436ca5e7b68d4b820c8c --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision ba995699c252120c1dfcbf13e0043993a804abe6) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision ba813ea0cf758315d5d6436ca5e7b68d4b820c8c) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.tool.assessment.service; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.util.ArrayList; @@ -48,9 +49,6 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.apache.poi.ss.usermodel.IndexedColors; -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.events.IEventNotificationService; import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.service.ILearnerService; @@ -112,6 +110,10 @@ import org.lamsfoundation.lams.util.NumberUtil; import org.lamsfoundation.lams.util.audit.IAuditService; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Andrey Balan */ @@ -438,7 +440,7 @@ @Override public void setAttemptStarted(Assessment assessment, AssessmentUser assessmentUser, Long toolSessionId) { Set questions = assessment.getQuestions(); - + AssessmentResult lastResult = getLastAssessmentResult(assessment.getUid(), assessmentUser.getUserId()); if (lastResult != null) { @@ -467,7 +469,7 @@ assessmentResultDao.saveObject(lastResult); return; - // mark previous attempt as being not the latest any longer + // mark previous attempt as being not the latest any longer } else { lastResult.setLatest(null); assessmentResultDao.saveObject(lastResult); @@ -539,7 +541,8 @@ for (QuestionDTO questionDto : questionsForOnePage) { // in case single MarkHedging question needs to be stored -- search for that question - if ((singleMarkHedgingQuestionUid != null) && !questionDto.getUid().equals(singleMarkHedgingQuestionUid)) { + if ((singleMarkHedgingQuestionUid != null) + && !questionDto.getUid().equals(singleMarkHedgingQuestionUid)) { continue; } @@ -596,24 +599,24 @@ * @param isAutosave * in case of autosave there is no need to calculate marks * @return grade that user scored by answering that question - * @throws NoSuchMethodException - * @throws InvocationTargetException - * @throws IllegalAccessException + * @throws NoSuchMethodException + * @throws InvocationTargetException + * @throws IllegalAccessException */ - private float storeUserAnswer(AssessmentResult assessmentResult, QuestionDTO questionDto, boolean isAutosave) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { + private float storeUserAnswer(AssessmentResult assessmentResult, QuestionDTO questionDto, boolean isAutosave) + throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Assessment assessment = assessmentResult.getAssessment(); - + AssessmentQuestionResult questionResult = null; // get questionResult from DB instance of AssessmentResult for (AssessmentQuestionResult questionResultIter : assessmentResult.getQuestionResults()) { if (questionDto.getUid().equals(questionResultIter.getAssessmentQuestion().getUid())) { questionResult = questionResultIter; } } - - //if teacher edited content in monitor (modified question) it led to removal if autosaved questionResult - if (assessment.isContentModifiedInMonitor(assessmentResult.getStartDate()) - && questionResult == null) { + + //if teacher edited content in monitor (modified question) it led to removal if autosaved questionResult + if (assessment.isContentModifiedInMonitor(assessmentResult.getStartDate()) && questionResult == null) { //update questionDto AssessmentQuestion modifiedQuestion = assessmentQuestionDao.getByUid(questionDto.getUid()); QuestionDTO updatedQuestionDto = modifiedQuestion.getQuestionDTO(); @@ -705,7 +708,8 @@ java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE); } boolean isAnswerMatchedCurrentOption = (questionDto.getAnswerString() != null) - ? pattern.matcher(questionDto.getAnswerString().trim()).matches() : false; + ? pattern.matcher(questionDto.getAnswerString().trim()).matches() + : false; if (isAnswerMatchedCurrentOption) { mark = optionDto.getGrade() * maxMark; @@ -721,7 +725,8 @@ boolean isAnswerMatchedCurrentOption = false; try { float answerFloat = Float.valueOf(questionDto.getAnswerString()); - isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() - optionDto.getAcceptedError())) + isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() + - optionDto.getAcceptedError())) && (answerFloat <= (optionDto.getOptionFloat() + optionDto.getAcceptedError()))); } catch (Exception e) { } @@ -739,7 +744,8 @@ answerFloat = answerFloat / unit.getMultiplier(); isAnswerMatchedCurrentOption = ((answerFloat >= (optionDto.getOptionFloat() - optionDto.getAcceptedError())) - && (answerFloat <= (optionDto.getOptionFloat() + optionDto.getAcceptedError()))); + && (answerFloat <= (optionDto.getOptionFloat() + + optionDto.getAcceptedError()))); if (isAnswerMatchedCurrentOption) { break; } @@ -757,15 +763,16 @@ } } else if (questionDto.getType() == AssessmentConstants.QUESTION_TYPE_TRUE_FALSE) { - if ((questionDto.getAnswerBoolean() == questionDto.getCorrectAnswer()) && (questionDto.getAnswerString() != null)) { + if ((questionDto.getAnswerBoolean() == questionDto.getCorrectAnswer()) + && (questionDto.getAnswerString() != null)) { mark = maxMark; } } else if (questionDto.getType() == AssessmentConstants.QUESTION_TYPE_ORDERING) { float maxMarkForCorrectAnswer = maxMark / questionDto.getOptionDtos().size(); - TreeSet correctOptionSet = new TreeSet(new SequencableComparator()); + TreeSet correctOptionSet = new TreeSet<>(new SequencableComparator()); correctOptionSet.addAll(questionDto.getOptionDtos()); - ArrayList correctOptionList = new ArrayList(correctOptionSet); + ArrayList correctOptionList = new ArrayList<>(correctOptionSet); int i = 0; for (OptionDTO optionDto : questionDto.getOptionDtos()) { if (optionDto.getUid() == correctOptionList.get(i++).getUid()) { @@ -934,7 +941,7 @@ @Override public List getReflectList(Long contentId) { - List reflectList = new LinkedList(); + List reflectList = new LinkedList<>(); List sessionList = assessmentSessionDao.getByContentId(contentId); for (AssessmentSession session : sessionList) { @@ -985,22 +992,28 @@ @Override public List getSessionDtos(Long contentId, boolean includeStatistics) { - List sessionDtos = new ArrayList(); + List sessionDtos = new ArrayList<>(); List sessionList = assessmentSessionDao.getByContentId(contentId); for (AssessmentSession session : sessionList) { Long sessionId = session.getSessionId(); SessionDTO sessionDto = new SessionDTO(sessionId, session.getSessionName()); //for statistics tab - if ( includeStatistics ) { + if (includeStatistics) { int countUsers = assessmentUserDao.getCountUsersBySession(sessionId, ""); sessionDto.setNumberLearners(countUsers); Object[] markStats = assessmentUserDao.getStatsMarksBySession(sessionId); - if ( markStats != null ) { - sessionDto.setMinMark(markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[0], (Locale)null, 2) : "0.00"); - sessionDto.setAvgMark(markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[1], (Locale)null, 2) : "0.00"); - sessionDto.setMaxMark(markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[2], (Locale)null, 2) : "0.00"); + if (markStats != null) { + sessionDto.setMinMark(markStats[0] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); + sessionDto.setAvgMark(markStats[1] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); + sessionDto.setMaxMark(markStats[2] != null + ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); } } @@ -1014,20 +1027,26 @@ public LeaderResultsDTO getLeaderResultsDTOForLeaders(Long contentId) { LeaderResultsDTO newDto = new LeaderResultsDTO(contentId); Object[] markStats = assessmentUserDao.getStatsMarksForLeaders(contentId); - if ( markStats != null ) { - newDto.setMinMark(markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[0], (Locale)null, 2) : "0.00"); - newDto.setAvgMark(markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[1], (Locale)null, 2) : "0.00"); - newDto.setMaxMark(markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float)markStats[2], (Locale)null, 2) : "0.00"); - newDto.setNumberGroupsLeaderFinished((Integer)markStats[3]); + if (markStats != null) { + newDto.setMinMark( + markStats[0] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[0], (Locale) null, 2) + : "0.00"); + newDto.setAvgMark( + markStats[1] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[1], (Locale) null, 2) + : "0.00"); + newDto.setMaxMark( + markStats[2] != null ? NumberUtil.formatLocalisedNumber((Float) markStats[2], (Locale) null, 2) + : "0.00"); + newDto.setNumberGroupsLeaderFinished((Integer) markStats[3]); } return newDto; } - + @Override public AssessmentResultDTO getUserMasterDetail(Long sessionId, Long userId) { AssessmentResultDTO resultDto = new AssessmentResultDTO(); resultDto.setSessionId(sessionId); - + AssessmentResult lastFinishedResult = assessmentResultDao.getLastFinishedAssessmentResultByUser(sessionId, userId); if (lastFinishedResult != null) { @@ -1036,13 +1055,13 @@ Set questionResults = lastFinishedResult.getQuestionResults(); //prepare list of the questions to display in user master detail table, filtering out questions that aren't supposed to be answered - SortedSet questionResultsToDisplay = new TreeSet( + SortedSet questionResultsToDisplay = new TreeSet<>( new AssessmentQuestionResultComparator()); //in case there is at least one random question - we need to show all questions if (assessment.hasRandomQuestion()) { questionResultsToDisplay.addAll(questionResults); - //otherwise show only questions from the question list + //otherwise show only questions from the question list } else { for (QuestionReference reference : questionReferences) { for (AssessmentQuestionResult questionResult : questionResults) { @@ -1064,7 +1083,7 @@ @Override public UserSummary getUserSummary(Long contentId, Long userId, Long sessionId) { Assessment assessment = assessmentDao.getByContentId(contentId); - + UserSummary userSummary = new UserSummary(); AssessmentUser user = assessmentUserDao.getUserByUserIDAndSessionID(userId, sessionId); userSummary.setUser(user); @@ -1079,11 +1098,11 @@ if (lastFinishedResult != null) { userSummary.setLastAttemptGrade(lastFinishedResult.getGrade()); } - + if (!results.isEmpty()) { //prepare list of the questions to display, filtering out questions that aren't supposed to be answered - Set questions = new TreeSet(); + Set questions = new TreeSet<>(); //in case there is at least one random question - we need to show all questions in a drop down select if (assessment.hasRandomQuestion()) { questions.addAll(assessment.getQuestions()); @@ -1096,12 +1115,12 @@ } //prepare list of UserSummaryItems - ArrayList userSummaryItems = new ArrayList(); + ArrayList userSummaryItems = new ArrayList<>(); for (AssessmentQuestion question : questions) { UserSummaryItem userSummaryItem = new UserSummaryItem(question); //find all questionResults that correspond to the current question - List questionResults = new ArrayList(); + List questionResults = new ArrayList<>(); for (AssessmentResult result : results) { for (AssessmentQuestionResult questionResult : result.getQuestionResults()) { if (question.getUid().equals(questionResult.getAssessmentQuestion().getUid())) { @@ -1136,27 +1155,27 @@ @Override public Map getQuestionSummaryForExport(Assessment assessment) { - Map questionSummaries = new LinkedHashMap(); + Map questionSummaries = new LinkedHashMap<>(); if (assessment.getQuestions() == null) { return questionSummaries; } - SortedSet sessions = new TreeSet(new AssessmentSessionComparator()); + SortedSet sessions = new TreeSet<>(new AssessmentSessionComparator()); sessions.addAll(assessmentSessionDao.getByContentId(assessment.getContentId())); List assessmentResults = assessmentResultDao .getLastFinishedAssessmentResults(assessment.getContentId()); - Map userUidToResultMap = new HashMap(); + Map userUidToResultMap = new HashMap<>(); for (AssessmentResult assessmentResult : assessmentResults) { userUidToResultMap.put(assessmentResult.getUser().getUid(), assessmentResult); } - Map> sessionIdToUsersMap = new HashMap>(); + Map> sessionIdToUsersMap = new HashMap<>(); for (AssessmentSession session : sessions) { Long sessionId = session.getSessionId(); - List users = new ArrayList(); + List users = new ArrayList<>(); // in case of leader aware tool show only leaders' responses if (assessment.isUseSelectLeaderToolOuput()) { @@ -1176,14 +1195,14 @@ QuestionSummary questionSummary = new QuestionSummary(); questionSummary.setQuestion(question); - List> questionResults = new ArrayList>(); + List> questionResults = new ArrayList<>(); for (AssessmentSession session : sessions) { Long sessionId = session.getSessionId(); List users = sessionIdToUsersMap.get(sessionId); - ArrayList sessionQuestionResults = new ArrayList(); + ArrayList sessionQuestionResults = new ArrayList<>(); for (AssessmentUser user : users) { AssessmentResult assessmentResult = userUidToResultMap.get(user.getUid()); AssessmentQuestionResult questionResult = null; @@ -1232,12 +1251,12 @@ @Override public LinkedHashMap exportSummary(Assessment assessment, List sessionDtos, boolean showUserNames) { - LinkedHashMap dataToExport = new LinkedHashMap(); + LinkedHashMap dataToExport = new LinkedHashMap<>(); final ExcelCell[] EMPTY_ROW = new ExcelCell[0]; // -------------- First tab: Summary ---------------------------------------------------- if (showUserNames) { - ArrayList summaryTab = new ArrayList(); + ArrayList summaryTab = new ArrayList<>(); if (sessionDtos != null) { for (SessionDTO sessionDTO : sessionDtos) { @@ -1248,8 +1267,8 @@ ExcelCell[] sessionTitle = new ExcelCell[1]; sessionTitle[0] = new ExcelCell(sessionDTO.getSessionName(), true); summaryTab.add(sessionTitle); - - List userDtos = new ArrayList(); + + List userDtos = new ArrayList<>(); // in case of UseSelectLeaderToolOuput - display only one user if (assessment.isUseSelectLeaderToolOuput()) { @@ -1275,12 +1294,15 @@ userDtos = getPagedUsersBySession(sessionId, 0, countSessionUsers, "userName", "ASC", ""); } - ArrayList summaryTabLearnerList = new ArrayList(); - + ArrayList summaryTabLearnerList = new ArrayList<>(); + ExcelCell[] summaryRowTitle = new ExcelCell[3]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.export.user.id"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[0] = new ExcelCell(getMessage("label.export.user.id"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[1] = new ExcelCell(getMessage("label.monitoring.summary.user.name"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[2] = new ExcelCell(getMessage("label.monitoring.summary.total"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); summaryTabLearnerList.add(summaryRowTitle); float minGrade = -9999999; @@ -1295,18 +1317,22 @@ userResultRow[2] = new ExcelCell(grade, false); summaryTabLearnerList.add(userResultRow); - if ( grade < minGrade || minGrade == -9999999 ) + if (grade < minGrade || minGrade == -9999999) { minGrade = grade; - if ( grade > maxGrade ) + } + if (grade > maxGrade) { maxGrade = grade; + } } - if ( minGrade == -9999999) + if (minGrade == -9999999) { minGrade = 0; + } - LinkedHashMap markSummary = getMarksSummaryForSession(userDtos, minGrade, maxGrade, 10); + LinkedHashMap markSummary = getMarksSummaryForSession(userDtos, minGrade, maxGrade, + 10); // work out total marks so we can do percentages. need as float for the correct divisions int totalNumEntries = 0; - for ( Map.Entry entry : markSummary.entrySet() ) { + for (Map.Entry entry : markSummary.entrySet()) { totalNumEntries += entry.getValue(); } @@ -1318,25 +1344,29 @@ summaryTab.add(minMaxRow); minMaxRow = new ExcelCell[2]; minMaxRow[0] = new ExcelCell(getMessage("label.lowest.mark"), true); - minMaxRow[1] = new ExcelCell((double)minGrade, false); + minMaxRow[1] = new ExcelCell((double) minGrade, false); summaryTab.add(minMaxRow); minMaxRow = new ExcelCell[2]; minMaxRow[0] = new ExcelCell(getMessage("label.highest.mark"), true); - minMaxRow[1] = new ExcelCell((double)maxGrade, false); + minMaxRow[1] = new ExcelCell((double) maxGrade, false); summaryTab.add(minMaxRow); - + summaryTab.add(EMPTY_ROW); ExcelCell[] binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(getMessage("label.authoring.basic.list.header.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[1] = new ExcelCell(getMessage("label.number.learners"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - binSummaryRow[2] = new ExcelCell(getMessage("label.percentage"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[0] = new ExcelCell(getMessage("label.authoring.basic.list.header.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[1] = new ExcelCell(getMessage("label.number.learners"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + binSummaryRow[2] = new ExcelCell(getMessage("label.percentage"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); summaryTab.add(binSummaryRow); - float totalNumEntriesAsFloat = (float) totalNumEntries; - for ( Map.Entry entry : markSummary.entrySet() ) { + float totalNumEntriesAsFloat = totalNumEntries; + for (Map.Entry entry : markSummary.entrySet()) { binSummaryRow = new ExcelCell[3]; - binSummaryRow[0] = new ExcelCell(entry.getKey(),false); - binSummaryRow[1] = new ExcelCell(entry.getValue(),false); - binSummaryRow[2] = new ExcelCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100),false); + binSummaryRow[0] = new ExcelCell(entry.getKey(), false); + binSummaryRow[1] = new ExcelCell(entry.getValue(), false); + binSummaryRow[2] = new ExcelCell(Math.round(entry.getValue() / totalNumEntriesAsFloat * 100), + false); summaryTab.add(binSummaryRow); } summaryTab.add(EMPTY_ROW); @@ -1353,7 +1383,7 @@ // ------------------------------------------------------------------ // -------------- Second tab: Question Summary ---------------------- - ArrayList questionSummaryTab = new ArrayList(); + ArrayList questionSummaryTab = new ArrayList<>(); // Create the question summary ExcelCell[] summaryTitle = new ExcelCell[1]; @@ -1393,13 +1423,13 @@ ExcelCell.BORDER_STYLE_BOTTOM_THIN); int questionNumber = 1; - + for (AssessmentQuestion question : questions) { int colsNum = showUserNames ? 10 : 9; ExcelCell[] questionTitle = new ExcelCell[1]; - questionTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question") + " " - + questionNumber++, true); + questionTitle[0] = new ExcelCell( + getMessage("label.monitoring.question.summary.question") + " " + questionNumber++, true); questionSummaryTab.add(questionTitle); // set up the summary table data for the top of the question area. @@ -1409,16 +1439,16 @@ || question.getType() == AssessmentConstants.QUESTION_TYPE_TRUE_FALSE; // For MC, Numeric & Short Answer Key is optionUid, Value is number of answers // For True/False Key 0 is false and Key 1 is true - Map summaryOfAnswers = new HashMap(); + Map summaryOfAnswers = new HashMap<>(); Integer summaryNACount = 0; Long trueKey = 1L; Long falseKey = 0L; if (doSummaryTable) { questionSummaryTab.add(startSummaryTable(question, summaryOfAnswers, trueKey, falseKey)); } - - ArrayList questionSummaryTabTemp = new ArrayList(); + ArrayList questionSummaryTabTemp = new ArrayList<>(); + //add question title row if (question.getType() == AssessmentConstants.QUESTION_TYPE_MARK_HEDGING) { count = 0; @@ -1499,9 +1529,10 @@ } else { userResultRow[count++] = new ExcelCell( AssessmentEscapeUtils.printResponsesForExcelExport(questionResult), false); - - if ( doSummaryTable ) { - summaryNACount = updateSummaryCounts(question, questionResult, summaryOfAnswers, summaryNACount); + + if (doSummaryTable) { + summaryNACount = updateSummaryCounts(question, questionResult, summaryOfAnswers, + summaryNACount); } } @@ -1529,10 +1560,11 @@ } if (doSummaryTable) { - questionSummaryTab.add(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); + questionSummaryTab + .add(outputSummaryTable(question, summaryOfAnswers, summaryNACount, trueKey, falseKey)); questionSummaryTab.add(EMPTY_ROW); } - + // Calculating the averages ExcelCell[] averageRow; @@ -1568,7 +1600,7 @@ questionSummaryTab.addAll(questionSummaryTabTemp); questionSummaryTab.add(averageRow); questionSummaryTab.add(EMPTY_ROW); - + } } @@ -1578,24 +1610,29 @@ // ------------------------------------------------------------------ // -------------- Third tab: User Summary --------------------------- - ArrayList userSummaryTab = new ArrayList(); + ArrayList userSummaryTab = new ArrayList<>(); // Create the question summary ExcelCell[] userSummaryTitle = new ExcelCell[1]; userSummaryTitle[0] = new ExcelCell(getMessage("label.export.user.summary"), true); userSummaryTab.add(userSummaryTitle); ExcelCell[] summaryRowTitle = new ExcelCell[5]; - summaryRowTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[1] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[2] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[3] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); - summaryRowTitle[4] = new ExcelCell(getMessage("label.monitoring.question.summary.average.mark"), true, ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[0] = new ExcelCell(getMessage("label.monitoring.question.summary.question"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[1] = new ExcelCell(getMessage("label.authoring.basic.list.header.type"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[2] = new ExcelCell(getMessage("label.authoring.basic.penalty.factor"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[3] = new ExcelCell(getMessage("label.monitoring.question.summary.default.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); + summaryRowTitle[4] = new ExcelCell(getMessage("label.monitoring.question.summary.average.mark"), true, + ExcelCell.BORDER_STYLE_BOTTOM_THIN); userSummaryTab.add(summaryRowTitle); Float totalGradesPossible = new Float(0); Float totalAverage = new Float(0); if (assessment.getQuestionReferences() != null) { - Set questionReferences = new TreeSet(new SequencableComparator()); + Set questionReferences = new TreeSet<>(new SequencableComparator()); questionReferences.addAll(assessment.getQuestionReferences()); int randomQuestionsCount = 1; @@ -1651,7 +1688,7 @@ if (sessionDtos != null) { List assessmentResults = assessmentResultDao .getLastFinishedAssessmentResults(assessment.getContentId()); - Map userUidToResultMap = new HashMap(); + Map userUidToResultMap = new HashMap<>(); for (AssessmentResult assessmentResult : assessmentResults) { userUidToResultMap.put(assessmentResult.getUser().getUid(), assessmentResult); } @@ -1763,30 +1800,26 @@ summaryTable = new ExcelCell[question.getOptions().size() + 1]; for (AssessmentQuestionOption option : question.getOptions()) { summaryOfAnswers.put(option.getUid(), 0); - StringBuilder bldr = new StringBuilder(getMessage("label.authoring.basic.option.answer")) - .append(" ") - .append(i + 1) - .append(" - "); - if ( question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL ) { - bldr.append(option.getOptionFloat()) - .append(" +- ") - .append(option.getAcceptedError()); + StringBuilder bldr = new StringBuilder(getMessage("label.authoring.basic.option.answer")).append(" ") + .append(i + 1).append(" - "); + if (question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL) { + bldr.append(option.getOptionFloat()).append(" +- ").append(option.getAcceptedError()); } else { bldr.append(option.getOptionString().replaceAll("\\<.*?\\>", "")); } summaryTable[i] = new ExcelCell(bldr.toString(), false); i++; } - if ( question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE ) { - summaryTable[i++] = new ExcelCell(getMessage("label.not.answered"), false); + if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE) { + summaryTable[i++] = new ExcelCell(getMessage("label.not.answered"), false); } else { - summaryTable[i++] = new ExcelCell(getMessage("label.other"), false); + summaryTable[i++] = new ExcelCell(getMessage("label.other"), false); } } else { summaryTable = new ExcelCell[3]; summaryTable[0] = new ExcelCell(getMessage("label.authoring.true.false.true"), false); summaryTable[1] = new ExcelCell(getMessage("label.authoring.true.false.false"), false); - summaryTable[2] = new ExcelCell(getMessage("label.not.answered"), false); + summaryTable[2] = new ExcelCell(getMessage("label.not.answered"), false); summaryOfAnswers.put(trueKey, 0); summaryOfAnswers.put(falseKey, 0); } @@ -1803,11 +1836,10 @@ if (optionAnswer.getAnswerBoolean()) { Integer currentCount = summaryOfAnswers.get(optionAnswer.getOptionUid()); if (currentCount == null) { - log.error("Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " - + questionResult.getUid() - + " OptionUid " - + optionAnswer.getOptionUid() - + " question " + question.getUid()); + log.error( + "Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " + + questionResult.getUid() + " OptionUid " + optionAnswer.getOptionUid() + + " question " + question.getUid()); } else { summaryOfAnswers.put(optionAnswer.getOptionUid(), currentCount + 1); foundOption = true; @@ -1824,12 +1856,10 @@ if (submittedUid != null) { Integer currentCount = summaryOfAnswers.get(submittedUid); if (currentCount == null) { - log.error("Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " - + questionResult.getUid() - + " submittedOptionUid " - + submittedUid - + " question " - + question.getUid()); + log.error( + "Assessment Export: Unable to count answer in summary, refers to an unexpected option. QuestionResult " + + questionResult.getUid() + " submittedOptionUid " + submittedUid + " question " + + question.getUid()); } else { summaryOfAnswers.put(submittedUid, currentCount + 1); } @@ -1850,39 +1880,38 @@ private String valueAsPercentage(Integer value, int total) { Double percentage = (double) value / total * 100; - return NumberUtil.formatLocalisedNumber(percentage, (Locale)null, 2) + "%"; - } - + return NumberUtil.formatLocalisedNumber(percentage, (Locale) null, 2) + "%"; + } + private ExcelCell[] outputSummaryTable(AssessmentQuestion question, Map summaryOfAnswers, Integer summaryNACount, Long trueKey, Long falseKey) { - ExcelCell[] summaryTable = new ExcelCell[summaryOfAnswers.size()+1]; + ExcelCell[] summaryTable = new ExcelCell[summaryOfAnswers.size() + 1]; int total = summaryNACount; - for ( int value : summaryOfAnswers.values() ) { - total += value; + for (int value : summaryOfAnswers.values()) { + total += value; } int i = 0; if (question.getType() == AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE || question.getType() == AssessmentConstants.QUESTION_TYPE_SHORT_ANSWER - || question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL ) { - for (AssessmentQuestionOption option : question.getOptions()) { - summaryTable[i] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(option.getUid()), total), false); - if ( option.getGrade() > 0 ) { - summaryTable[i].setColor(IndexedColors.GREEN); + || question.getType() == AssessmentConstants.QUESTION_TYPE_NUMERICAL) { + for (AssessmentQuestionOption option : question.getOptions()) { + summaryTable[i] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(option.getUid()), total), false); + if (option.getGrade() > 0) { + summaryTable[i].setColor(IndexedColors.GREEN); + } + i++; } - i++; - } - summaryTable[i++] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); + summaryTable[i++] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); } else { - summaryTable = new ExcelCell[3]; - summaryTable[0] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(trueKey), total), false); - summaryTable[1] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(falseKey), total), false); - summaryTable[2] = new ExcelCell(valueAsPercentage(summaryNACount,total), false); - summaryTable[question.getCorrectAnswer() ? 0 : 1].setColor(IndexedColors.GREEN); + summaryTable = new ExcelCell[3]; + summaryTable[0] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(trueKey), total), false); + summaryTable[1] = new ExcelCell(valueAsPercentage(summaryOfAnswers.get(falseKey), total), false); + summaryTable[2] = new ExcelCell(valueAsPercentage(summaryNACount, total), false); + summaryTable[question.getCorrectAnswer() ? 0 : 1].setColor(IndexedColors.GREEN); } return summaryTable; } - /** * Used only for excell export (for getUserSummaryData() method). */ @@ -1923,11 +1952,11 @@ // When changing a mark for user and isUseSelectLeaderToolOuput is true, the mark should be propagated to all // students within the group - List users = new ArrayList(); + List users = new ArrayList<>(); if (assessment.isUseSelectLeaderToolOuput()) { users = getUsersBySession(toolSessionId); } else { - users = new ArrayList(); + users = new ArrayList<>(); AssessmentUser user = assessmentResult.getUser(); users.add(user); } @@ -1971,7 +2000,7 @@ List deletedReferences) { // create list of modified questions - List modifiedQuestions = new ArrayList(); + List modifiedQuestions = new ArrayList<>(); for (AssessmentQuestion oldQuestion : oldQuestions) { for (AssessmentQuestion newQuestion : newQuestions) { if (oldQuestion.getUid().equals(newQuestion.getUid())) { @@ -2017,7 +2046,7 @@ // create list of modified references // modifiedReferences holds pairs newReference -> oldReference.getDefaultGrade() - Map modifiedReferences = new HashMap(); + Map modifiedReferences = new HashMap<>(); for (QuestionReference oldReference : oldReferences) { for (QuestionReference newReference : newReferences) { if (oldReference.getUid().equals(newReference.getUid()) @@ -2028,7 +2057,7 @@ } // create list of added references - List addedReferences = new ArrayList(); + List addedReferences = new ArrayList<>(); for (QuestionReference newReference : newReferences) { boolean isNewReferenceMetInOldReferences = false; @@ -2056,7 +2085,7 @@ user.getUserId()); AssessmentResult lastFinishedAssessmentResult = (assessmentResults.isEmpty()) ? null : assessmentResults.get(assessmentResults.size() - 1); - + //add autosave assessmentResult as well AssessmentResult lastAssessmentResult = getLastAssessmentResult(assessment.getUid(), user.getUserId()); if (lastAssessmentResult != null && lastAssessmentResult.getFinishDate() == null) { @@ -2137,7 +2166,7 @@ } // find all question answers from random question reference - ArrayList nonRandomQuestionAnswers = new ArrayList(); + ArrayList nonRandomQuestionAnswers = new ArrayList<>(); for (AssessmentQuestionResult questionAnswer : questionAnswers) { for (QuestionReference reference : newReferences) { if (!reference.isRandomQuestion() && questionAnswer.getAssessmentQuestion().getUid() @@ -2245,7 +2274,7 @@ public boolean isGroupedActivity(long toolContentID) { return toolService.isGroupedActivity(toolContentID); } - + @Override public void auditLogStartEditingActivityInMonitor(long toolContentID) { toolService.auditLogStartEditingActivityInMonitor(toolContentID); @@ -2272,7 +2301,6 @@ eventNotificationService.notifyLessonMonitors(sessionId, message, false); } - @Override public List getMarksArray(Long sessionId) { return assessmentUserDao.getRawUserMarksBySession(sessionId); @@ -2283,66 +2311,70 @@ return assessmentUserDao.getRawLeaderMarksByToolContentId(toolContentId); } - private LinkedHashMap getMarksSummaryForSession(List userDtos, float minGrade, float maxGrade, Integer numBuckets) { + private LinkedHashMap getMarksSummaryForSession(List userDtos, float minGrade, + float maxGrade, Integer numBuckets) { - LinkedHashMap summary = new LinkedHashMap(); - TreeMap inProgress = new TreeMap(); - - if ( numBuckets == null ) + LinkedHashMap summary = new LinkedHashMap<>(); + TreeMap inProgress = new TreeMap<>(); + + if (numBuckets == null) { numBuckets = 10; - + } + int bucketSize = 1; - int intMinGrade = (int)Math.floor(minGrade); + int intMinGrade = (int) Math.floor(minGrade); float gradeDifference = maxGrade - minGrade; - if ( gradeDifference <= 10 ) { - for ( int i= intMinGrade; i <= (int)Math.ceil(maxGrade); i++ ) { + if (gradeDifference <= 10) { + for (int i = intMinGrade; i <= (int) Math.ceil(maxGrade); i++) { inProgress.put(i, 0); } } else { int intGradeDifference = (int) Math.ceil(gradeDifference); - bucketSize = (int) Math.ceil(intGradeDifference / numBuckets); - for ( int i=intMinGrade; i <= maxGrade; i = i+bucketSize ) { + bucketSize = (int) Math.ceil(intGradeDifference / numBuckets); + for (int i = intMinGrade; i <= maxGrade; i = i + bucketSize) { inProgress.put(i, 0); } } - + for (AssessmentUserDTO userDto : userDtos) { float grade = userDto.getGrade(); int bucketStart = intMinGrade; - int bucketStop = bucketStart+bucketSize; + int bucketStop = bucketStart + bucketSize; boolean looking = true; - while ( bucketStart <= maxGrade && looking ) { - if ( grade >= bucketStart && grade < bucketStop ) { + while (bucketStart <= maxGrade && looking) { + if (grade >= bucketStart && grade < bucketStop) { inProgress.put(bucketStart, inProgress.get(bucketStart) + 1); looking = false; } else { bucketStart = bucketStop; - bucketStop = bucketStart+bucketSize; + bucketStop = bucketStart + bucketSize; } } } - - for ( Map.Entry entry : inProgress.entrySet() ) { + + for (Map.Entry entry : inProgress.entrySet()) { String key; - if ( bucketSize == 1 ) + if (bucketSize == 1) { key = entry.getKey().toString(); - else { - if ( maxGrade >= entry.getKey() && maxGrade <= entry.getKey()+bucketSize-1) { - if ( (int)maxGrade == entry.getKey() ) - key = NumberUtil.formatLocalisedNumber(maxGrade, (Locale)null, 2); - else + } else { + if (maxGrade >= entry.getKey() && maxGrade <= entry.getKey() + bucketSize - 1) { + if ((int) maxGrade == entry.getKey()) { + key = NumberUtil.formatLocalisedNumber(maxGrade, (Locale) null, 2); + } else { key = new StringBuilder().append(entry.getKey()).append(" - ") - .append(NumberUtil.formatLocalisedNumber(maxGrade, (Locale)null, 2)).toString(); + .append(NumberUtil.formatLocalisedNumber(maxGrade, (Locale) null, 2)).toString(); + } } else { - key = new StringBuilder().append(entry.getKey()).append(" - ").append(entry.getKey()+bucketSize-.01).toString(); + key = new StringBuilder().append(entry.getKey()).append(" - ") + .append(entry.getKey() + bucketSize - .01).toString(); } } summary.put(key, entry.getValue()); } - + return summary; } - + // ***************************************************************************** // private methods // ***************************************************************************** @@ -2779,116 +2811,126 @@ Date startDate = null; Date finishDate = null; for (AssessmentResult result : results) { - if (startDate == null || (result.getStartDate() != null && result.getStartDate().before(startDate))) + if (startDate == null || (result.getStartDate() != null && result.getStartDate().before(startDate))) { startDate = result.getStartDate(); - if (finishDate == null || (result.getFinishDate() != null && result.getFinishDate().after(finishDate))) + } + if (finishDate == null || (result.getFinishDate() != null && result.getFinishDate().after(finishDate))) { finishDate = result.getFinishDate(); + } } - if (learner.isSessionFinished()) + if (learner.isSessionFinished()) { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_COMPLETED, startDate, finishDate); - else + } else { return new ToolCompletionStatus(ToolCompletionStatus.ACTIVITY_ATTEMPTED, startDate, null); + } } // ****************** REST methods ************************* /** * Rest call to create a new Assessment content. Required fields in toolContentJSON: "title", "instructions", * "questions", "firstName", "lastName", "lastName", "questions" and "references". * - * The questions entry should be a JSONArray containing JSON objects, which in turn must contain "questionTitle", + * The questions entry should be a ArrayNode containing JSON objects, which in turn must contain "questionTitle", * "questionText", "displayOrder" (Integer), "type" (Integer). If the type is Multiple Choice, Numerical or Matching - * Pairs then a JSONArray "answers" is required. + * Pairs then a ArrayNode "answers" is required. * - * The answers entry should be JSONArray containing JSON objects, which in turn must contain "answerText" or + * The answers entry should be ArrayNode containing JSON objects, which in turn must contain "answerText" or * "answerFloat", "displayOrder" (Integer), "grade" (Integer). * - * The references entry should be a JSONArray containing JSON objects, which in turn must contain "displayOrder" + * The references entry should be a ArrayNode containing JSON objects, which in turn must contain "displayOrder" * (Integer), "questionDisplayOrder" (Integer - to match to the question). It may also have "defaultGrade" (Integer) * and "randomQuestion" (Boolean) + * + * @throws IOException */ @SuppressWarnings("unchecked") @Override - public void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) - throws JSONException { + public void createRestToolContent(Integer userID, Long toolContentID, ObjectNode toolContentJSON) + throws IOException { Assessment assessment = new Assessment(); assessment.setContentId(toolContentID); - assessment.setTitle(toolContentJSON.getString(RestTags.TITLE)); - assessment.setInstructions(toolContentJSON.getString(RestTags.INSTRUCTIONS)); + assessment.setTitle(toolContentJSON.get(RestTags.TITLE).asText()); + assessment.setInstructions(toolContentJSON.get(RestTags.INSTRUCTIONS).asText()); assessment.setCreated(new Date()); - assessment.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - assessment.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, (String) null)); - assessment.setAllowGradesAfterAttempt(JsonUtil.opt(toolContentJSON, "allowGradesAfterAttempt", Boolean.FALSE)); - assessment.setAllowHistoryResponses(JsonUtil.opt(toolContentJSON, "allowHistoryResponses", Boolean.FALSE)); + assessment.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + assessment.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS)); + assessment.setAllowGradesAfterAttempt( + JsonUtil.optBoolean(toolContentJSON, "allowGradesAfterAttempt", Boolean.FALSE)); + assessment + .setAllowHistoryResponses(JsonUtil.optBoolean(toolContentJSON, "allowHistoryResponses", Boolean.FALSE)); assessment.setAllowOverallFeedbackAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowOverallFeedbackAfterQuestion", Boolean.FALSE)); - assessment.setAllowQuestionFeedback(JsonUtil.opt(toolContentJSON, "allowQuestionFeedback", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "allowOverallFeedbackAfterQuestion", Boolean.FALSE)); + assessment + .setAllowQuestionFeedback(JsonUtil.optBoolean(toolContentJSON, "allowQuestionFeedback", Boolean.FALSE)); assessment.setAllowRightAnswersAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowRightAnswersAfterQuestion", Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, "allowRightAnswersAfterQuestion", Boolean.FALSE)); assessment.setAllowWrongAnswersAfterQuestion( - JsonUtil.opt(toolContentJSON, "allowWrongAnswersAfterQuestion", Boolean.FALSE)); - assessment.setAttemptsAllowed(JsonUtil.opt(toolContentJSON, "attemptsAllows", 1)); + JsonUtil.optBoolean(toolContentJSON, "allowWrongAnswersAfterQuestion", Boolean.FALSE)); + assessment.setAttemptsAllowed(JsonUtil.optInt(toolContentJSON, "attemptsAllows", 1)); assessment.setDefineLater(false); - assessment.setDisplaySummary(JsonUtil.opt(toolContentJSON, "displaySummary", Boolean.FALSE)); + assessment.setDisplaySummary(JsonUtil.optBoolean(toolContentJSON, "displaySummary", Boolean.FALSE)); assessment.setNotifyTeachersOnAttemptCompletion( - JsonUtil.opt(toolContentJSON, "notifyTeachersOnAttemptCompletion", Boolean.FALSE)); - assessment.setNumbered(JsonUtil.opt(toolContentJSON, "numbered", Boolean.TRUE)); - assessment.setPassingMark(JsonUtil.opt(toolContentJSON, "passingMark", 0)); - assessment.setQuestionsPerPage(JsonUtil.opt(toolContentJSON, "questionsPerPage", 0)); - assessment.setReflectInstructions(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); - assessment.setReflectOnActivity(JsonUtil.opt(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); - assessment.setShuffled(JsonUtil.opt(toolContentJSON, "shuffled", Boolean.FALSE)); - assessment.setTimeLimit(JsonUtil.opt(toolContentJSON, "timeLimit", 0)); + JsonUtil.optBoolean(toolContentJSON, "notifyTeachersOnAttemptCompletion", Boolean.FALSE)); + assessment.setNumbered(JsonUtil.optBoolean(toolContentJSON, "numbered", Boolean.TRUE)); + assessment.setPassingMark(JsonUtil.optInt(toolContentJSON, "passingMark", 0)); + assessment.setQuestionsPerPage(JsonUtil.optInt(toolContentJSON, "questionsPerPage", 0)); + assessment.setReflectInstructions(JsonUtil.optString(toolContentJSON, RestTags.REFLECT_INSTRUCTIONS, "")); + assessment.setReflectOnActivity( + JsonUtil.optBoolean(toolContentJSON, RestTags.REFLECT_ON_ACTIVITY, Boolean.FALSE)); + assessment.setShuffled(JsonUtil.optBoolean(toolContentJSON, "shuffled", Boolean.FALSE)); + assessment.setTimeLimit(JsonUtil.optInt(toolContentJSON, "timeLimit", 0)); assessment.setUseSelectLeaderToolOuput( - JsonUtil.opt(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); + JsonUtil.optBoolean(toolContentJSON, RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, Boolean.FALSE)); // submission deadline set in monitoring if (toolContentJSON.has("overallFeedback")) { - throw new JSONException( + throw new IOException( "Assessment Tool does not support Overall Feedback for REST Authoring. " + toolContentJSON); } AssessmentUser assessmentUser = getUserByIDAndContent(userID.longValue(), toolContentID); if (assessmentUser == null) { assessmentUser = new AssessmentUser(); - assessmentUser.setFirstName(toolContentJSON.getString("firstName")); - assessmentUser.setLastName(toolContentJSON.getString("lastName")); - assessmentUser.setLoginName(toolContentJSON.getString("loginName")); + assessmentUser.setFirstName(toolContentJSON.get("firstName").asText()); + assessmentUser.setLastName(toolContentJSON.get("lastName").asText()); + assessmentUser.setLoginName(toolContentJSON.get("loginName").asText()); assessmentUser.setAssessment(assessment); } assessment.setCreatedBy(assessmentUser); // **************************** Set the question bank ********************* - JSONArray questions = toolContentJSON.getJSONArray("questions"); + ArrayNode questions = JsonUtil.optArray(toolContentJSON, "questions"); Set newQuestionSet = assessment.getQuestions(); // the Assessment constructor will set up the collection - for (int i = 0; i < questions.length(); i++) { - JSONObject questionJSONData = (JSONObject) questions.get(i); + for (JsonNode questionJSONData : questions) { AssessmentQuestion question = new AssessmentQuestion(); - short type = (short) questionJSONData.getInt("type"); + short type = JsonUtil.optInt(questionJSONData, "type").shortValue(); question.setType(type); - question.setTitle(questionJSONData.getString(RestTags.QUESTION_TITLE)); - question.setQuestion(questionJSONData.getString(RestTags.QUESTION_TEXT)); - question.setSequenceId(questionJSONData.getInt(RestTags.DISPLAY_ORDER)); + question.setTitle(questionJSONData.get(RestTags.QUESTION_TITLE).asText()); + question.setQuestion(questionJSONData.get(RestTags.QUESTION_TEXT).asText()); + question.setSequenceId(JsonUtil.optInt(questionJSONData, RestTags.DISPLAY_ORDER)); - question.setAllowRichEditor(JsonUtil.opt(questionJSONData, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); - question.setAnswerRequired(JsonUtil.opt(questionJSONData, "answerRequired", Boolean.FALSE)); - question.setCaseSensitive(JsonUtil.opt(questionJSONData, "caseSensitive", Boolean.FALSE)); - question.setCorrectAnswer(JsonUtil.opt(questionJSONData, "correctAnswer", Boolean.FALSE)); - question.setDefaultGrade(JsonUtil.opt(questionJSONData, "defaultGrade", 1)); - question.setFeedback(JsonUtil.opt(questionJSONData, "feedback", (String) null)); - question.setFeedbackOnCorrect(JsonUtil.opt(questionJSONData, "feedbackOnCorrect", (String) null)); - question.setFeedbackOnIncorrect(JsonUtil.opt(questionJSONData, "feedbackOnIncorrect", (String) null)); - question.setFeedbackOnPartiallyCorrect( - JsonUtil.opt(questionJSONData, "feedbackOnPartiallyCorrect", (String) null)); - question.setGeneralFeedback(JsonUtil.opt(questionJSONData, "generalFeedback", "")); - question.setMaxWordsLimit(JsonUtil.opt(questionJSONData, "maxWordsLimit", 0)); - question.setMinWordsLimit(JsonUtil.opt(questionJSONData, "minWordsLimit", 0)); - question.setMultipleAnswersAllowed(JsonUtil.opt(questionJSONData, "multipleAnswersAllowed", Boolean.FALSE)); + question.setAllowRichEditor( + JsonUtil.optBoolean(questionJSONData, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE)); + question.setAnswerRequired(JsonUtil.optBoolean(questionJSONData, "answerRequired", Boolean.FALSE)); + question.setCaseSensitive(JsonUtil.optBoolean(questionJSONData, "caseSensitive", Boolean.FALSE)); + question.setCorrectAnswer(JsonUtil.optBoolean(questionJSONData, "correctAnswer", Boolean.FALSE)); + question.setDefaultGrade(JsonUtil.optInt(questionJSONData, "defaultGrade", 1)); + question.setFeedback(JsonUtil.optString(questionJSONData, "feedback")); + question.setFeedbackOnCorrect(JsonUtil.optString(questionJSONData, "feedbackOnCorrect")); + question.setFeedbackOnIncorrect(JsonUtil.optString(questionJSONData, "feedbackOnIncorrect")); + question.setFeedbackOnPartiallyCorrect(JsonUtil.optString(questionJSONData, "feedbackOnPartiallyCorrect")); + question.setGeneralFeedback(JsonUtil.optString(questionJSONData, "generalFeedback", "")); + question.setMaxWordsLimit(JsonUtil.optInt(questionJSONData, "maxWordsLimit", 0)); + question.setMinWordsLimit(JsonUtil.optInt(questionJSONData, "minWordsLimit", 0)); + question.setMultipleAnswersAllowed( + JsonUtil.optBoolean(questionJSONData, "multipleAnswersAllowed", Boolean.FALSE)); question.setIncorrectAnswerNullifiesMark( - JsonUtil.opt(questionJSONData, "incorrectAnswerNullifiesMark", Boolean.FALSE)); - question.setPenaltyFactor(Float.parseFloat(JsonUtil.opt(questionJSONData, "penaltyFactor", "0.0"))); + JsonUtil.optBoolean(questionJSONData, "incorrectAnswerNullifiesMark", Boolean.FALSE)); + question.setPenaltyFactor(JsonUtil.optDouble(questionJSONData, "penaltyFactor", 0.0).floatValue()); // question.setUnits(units); Needed for numerical type question if ((type == AssessmentConstants.QUESTION_TYPE_MATCHING_PAIRS) @@ -2897,22 +2939,21 @@ || (type == AssessmentConstants.QUESTION_TYPE_MARK_HEDGING)) { if (!questionJSONData.has(RestTags.ANSWERS)) { - throw new JSONException("REST Authoring is missing answers for a question of type " + type - + ". Data:" + toolContentJSON); + throw new IOException("REST Authoring is missing answers for a question of type " + type + ". Data:" + + toolContentJSON); } - Set optionList = new LinkedHashSet(); - JSONArray optionsData = questionJSONData.getJSONArray(RestTags.ANSWERS); - for (int j = 0; j < optionsData.length(); j++) { - JSONObject answerData = (JSONObject) optionsData.get(j); + Set optionList = new LinkedHashSet<>(); + ArrayNode optionsData = JsonUtil.optArray(questionJSONData, RestTags.ANSWERS); + for (JsonNode answerData : optionsData) { AssessmentQuestionOption option = new AssessmentQuestionOption(); - option.setSequenceId(answerData.getInt(RestTags.DISPLAY_ORDER)); - option.setGrade(Float.parseFloat(answerData.getString("grade"))); - option.setCorrect(Boolean.parseBoolean(JsonUtil.opt(answerData, "correct", "false"))); - option.setAcceptedError(Float.parseFloat(JsonUtil.opt(answerData, "acceptedError", "0.0"))); - option.setFeedback(JsonUtil.opt(answerData, "feedback", (String) null)); - option.setOptionString(JsonUtil.opt(answerData, RestTags.ANSWER_TEXT, (String) null)); - option.setOptionFloat(Float.parseFloat(JsonUtil.opt(answerData, "answerFloat", "0.0"))); + option.setSequenceId(JsonUtil.optInt(answerData, RestTags.DISPLAY_ORDER)); + option.setGrade(answerData.get("grade").floatValue()); + option.setCorrect(JsonUtil.optBoolean(answerData, "correct", false)); + option.setAcceptedError(JsonUtil.optDouble(answerData, "acceptedError", 0.0).floatValue()); + option.setFeedback(JsonUtil.optString(answerData, "feedback")); + option.setOptionString(JsonUtil.optString(answerData, RestTags.ANSWER_TEXT)); + option.setOptionFloat(JsonUtil.optDouble(answerData, "answerFloat", 0.0).floatValue()); // option.setQuestion(question); can't find the use for this field yet! optionList.add(option); } @@ -2924,23 +2965,23 @@ } // **************************** Now set up the references to the questions in the bank ********************* - JSONArray references = toolContentJSON.getJSONArray("references"); + ArrayNode references = JsonUtil.optArray(toolContentJSON, "references"); Set newReferenceSet = assessment.getQuestionReferences(); // the Assessment constructor will set up the - // collection - for (int i = 0; i < references.length(); i++) { - JSONObject referenceJSONData = (JSONObject) references.get(i); + + ;// collection + for (JsonNode referenceJSONData : references) { QuestionReference reference = new QuestionReference(); reference.setType((short) 0); - reference.setDefaultGrade(JsonUtil.opt(referenceJSONData, "defaultGrade", 1)); - reference.setSequenceId(referenceJSONData.getInt(RestTags.DISPLAY_ORDER)); + reference.setDefaultGrade(JsonUtil.optInt(referenceJSONData, "defaultGrade", 1)); + reference.setSequenceId(JsonUtil.optInt(referenceJSONData, RestTags.DISPLAY_ORDER)); AssessmentQuestion matchingQuestion = matchQuestion(newQuestionSet, - referenceJSONData.getInt("questionDisplayOrder")); + JsonUtil.optInt(referenceJSONData, "questionDisplayOrder")); if (matchingQuestion == null) { - throw new JSONException("Unable to find matching question for displayOrder " + throw new IOException("Unable to find matching question for displayOrder " + referenceJSONData.get("questionDisplayOrder") + ". Data:" + toolContentJSON); } reference.setQuestion(matchingQuestion); - reference.setRandomQuestion(JsonUtil.opt(referenceJSONData, "randomQuestion", Boolean.FALSE)); + reference.setRandomQuestion(JsonUtil.optBoolean(referenceJSONData, "randomQuestion", Boolean.FALSE)); reference.setTitle(null); newReferenceSet.add(reference); } @@ -2962,10 +3003,10 @@ } // TODO Implement REST support for all types and then remove checkType method - void checkType(short type) throws JSONException { + void checkType(short type) throws IOException { if ((type != AssessmentConstants.QUESTION_TYPE_ESSAY) && (type != AssessmentConstants.QUESTION_TYPE_MULTIPLE_CHOICE)) { - throw new JSONException( + throw new IOException( "Assessment Tool does not support REST Authoring for anything but Essay Type and Multiple Choice. Found type " + type); }