Index: lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java =================================================================== diff -u -re0265c3507ca12f61524934309a32092296fe601 -r4c5a620700d152367d81a3ad8cf1d0f0b94f86ac --- lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java (.../Assessment.java) (revision e0265c3507ca12f61524934309a32092296fe601) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/template/Assessment.java (.../Assessment.java) (revision 4c5a620700d152367d81a3ad8cf1d0f0b94f86ac) @@ -54,11 +54,12 @@ int defaultGrade = 1; boolean multipleAnswersAllowed = false; // only used if type == 1 List answers = null; // only used if type == 1 + String uuid = null; // used when QTI gets imported and it contains QB question UUID public void setType(short type) { this.type = type; if (type == 1 && this.answers == null) { - this.answers = new LinkedList(); + this.answers = new LinkedList<>(); } } @@ -111,16 +112,26 @@ } public boolean isMultipleAnswersAllowed() { - return multipleAnswersAllowed; + return multipleAnswersAllowed; } public void setMultipleAnswersAllowed(boolean multipleAnswersAllowed) { - this.multipleAnswersAllowed = multipleAnswersAllowed; + this.multipleAnswersAllowed = multipleAnswersAllowed; } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + public ObjectNode getAsObjectNode(int displayOrder) { ObjectNode json = JsonNodeFactory.instance.objectNode(); json.put(RestTags.QUESTION_TITLE, title != null ? title : ""); json.put(RestTags.QUESTION_TEXT, text != null ? text : ""); + json.put(RestTags.QUESTION_UUID, uuid != null ? uuid : ""); json.put(RestTags.DISPLAY_ORDER, displayOrder); json.put("answerRequired", required); json.put("defaultGrade", defaultGrade); @@ -140,7 +151,6 @@ return json; } - public boolean validate(List errorMessages, ResourceBundle appBundle, MessageFormat formatter, Integer applicationExerciseNumber, String applicationExerciseTitle, Integer questionNumber) { boolean errorsExist = false; @@ -154,9 +164,9 @@ if (answers.size() == 0) { errorMessages.add(TextUtil.getText(appBundle, formatter, "authoring.error.application.exercise.must.have.answer.num", - new Object[] { applicationExerciseTitle, "\""+ title +"\"" })); + new Object[] { applicationExerciseTitle, "\"" + title + "\"" })); errorsExist = true; - } else if ( !multipleAnswersAllowed ){ + } else if (!multipleAnswersAllowed) { // multiple answers -> no validation, single answer -> must have one with 100% boolean found100percent = false; for (AssessMCAnswer answer : answers) { @@ -168,7 +178,7 @@ if (!found100percent) { errorMessages.add(TextUtil.getText(appBundle, formatter, "authoring.error.application.exercise.must.have.100.percent", - new Object[] { applicationExerciseTitle, "\""+ title +"\""})); + new Object[] { applicationExerciseTitle, "\"" + title + "\"" })); errorsExist = true; } } Index: lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateController.java =================================================================== diff -u -re0265c3507ca12f61524934309a32092296fe601 -r4c5a620700d152367d81a3ad8cf1d0f0b94f86ac --- lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateController.java (.../LdTemplateController.java) (revision e0265c3507ca12f61524934309a32092296fe601) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/template/web/LdTemplateController.java (.../LdTemplateController.java) (revision 4c5a620700d152367d81a3ad8cf1d0f0b94f86ac) @@ -79,14 +79,17 @@ /** * Base class for actions processing Learning Design templates. * - * A little history: This code was written when we were still using Struts but we were phasing it out. So it was written with the - * minimal of Struts code, which was then swapped to being the minimal Spring MVC. Now we are using Spring MVC it would + * A little history: This code was written when we were still using Struts but we were phasing it out. So it was written + * with the + * minimal of Struts code, which was then swapped to being the minimal Spring MVC. Now we are using Spring MVC it would * be nice to convert to using more Spring MVC features rather than adding parts piecemeal as the template pages - * become more complicated. Rather than relying on the web page to keep all the data and doing ajax updates, it would be - * nice to have a session form or the like backing the page. It would make it easier to have the templates load an existing - * design from the database for modification and make the processing when the template is saved so it doesn't do one huge + * become more complicated. Rather than relying on the web page to keep all the data and doing ajax updates, it would be + * nice to have a session form or the like backing the page. It would make it easier to have the templates load an + * existing + * design from the database for modification and make the processing when the template is saved so it doesn't do one + * huge * parse in one go. - * + * * Would also be nice to stop hardcoding the icons! * * @author Marcin Cieslak, Fiona Malikoff @@ -98,8 +101,8 @@ WebApplicationContext applictionContext; // Used to append the number to the group label - format as 2 digits so it sorts better. - NumberFormat groupNumberFormatter = new DecimalFormat("00"); - + NumberFormat groupNumberFormatter = new DecimalFormat("00"); + private static Logger log = Logger.getLogger(LdTemplateController.class); public static final int MAX_OPTION_COUNT = 6; public static final int MAX_FLOATING_ACTIVITY_OPTIONS = 6; // Hardcoded in the Flash client @@ -120,7 +123,7 @@ // icon strings found in the lams_learningdesign_activity table protected static final String ASSESSMENT_TOOL_SIGNATURE = "laasse10"; protected static final String ASSESSMENT_ICON = "tool/laasse10/images/icon_assessment.swf"; - protected static final String ASSESSMENT_TOOL_OUTPUT_DEFINITION = "learner.total.score"; + protected static final String ASSESSMENT_TOOL_OUTPUT_DEFINITION = "learner.total.score"; protected static final String CHAT_TOOL_SIGNATURE = "lachat11"; protected static final String CHAT_ICON = "tool/lachat11/images/icon_chat.swf"; protected static final String FORUM_TOOL_SIGNATURE = "lafrum11"; @@ -129,7 +132,7 @@ protected static final String LEADER_ICON = "tool/lalead11/images/icon_leaderselection.swf"; protected static final String MCQ_TOOL_SIGNATURE = "lamc11"; protected static final String MCQ_ICON = "tool/lamc11/images/icon_mcq.swf"; - protected static final String MCQ_TOOL_OUTPUT_DEFINITION = "learner.mark"; + protected static final String MCQ_TOOL_OUTPUT_DEFINITION = "learner.mark"; protected static final String NOTEBOOK_TOOL_SIGNATURE = "lantbk11"; protected static final String NOTEBOOK_ICON = "tool/lantbk11/images/icon_notebook.swf"; protected static final String NOTICEBOARD_TOOL_SIGNATURE = "lanb11"; @@ -140,7 +143,7 @@ protected static final String SHARE_RESOURCES_ICON = "tool/larsrc11/images/icon_rsrc.swf"; protected static final String SCRATCHIE_TOOL_SIGNATURE = "lascrt11"; protected static final String SCRATCHIE_ICON = "tool/lascrt11/images/icon_scratchie.swf"; - protected static final String SCRATCHIE_TOOL_OUTPUT_DEFINITION = "learner.mark"; + protected static final String SCRATCHIE_TOOL_OUTPUT_DEFINITION = "learner.mark"; protected static final String SCRIBE_TOOL_SIGNATURE = "lascrb11"; protected static final String SCRIBE_ICON = "tool/lascrb11/images/icon_scribe.swf"; protected static final String SUBMIT_TOOL_SIGNATURE = "lasbmt11"; @@ -208,7 +211,7 @@ return "authoring/template/tbl/tbl"; } - public String init(HttpServletRequest request, String forward ) throws Exception { + public String init(HttpServletRequest request, String forward) throws Exception { String contentFolderID = FileUtil.generateUniqueContentFolderID(); request.setAttribute(RestTags.CONTENT_FOLDER_ID, contentFolderID); return forward; @@ -327,7 +330,7 @@ } /** - * Create a title for this learning design, within the right length for the database. The userEnteredString is + * Create a title for this learning design, within the right length for the database. The userEnteredString is * capitalised and whitespace is removed. The call to saveLearningDesign will make it unique by appending a date * if needed. * @@ -390,7 +393,8 @@ } /* ************************************** Non-Tool Activity methods ******************************************** */ - protected ObjectNode createGateActivity(AtomicInteger uiid, int order, Integer[] layoutCoords, String activityTitle, String activityDescription) { + protected ObjectNode createGateActivity(AtomicInteger uiid, int order, Integer[] layoutCoords, String activityTitle, + String activityDescription) { ObjectNode activityJSON = JsonNodeFactory.instance.objectNode(); Integer[] pos = layoutCoords; @@ -406,9 +410,10 @@ activityJSON.put(AuthoringJsonTags.APPLY_GROUPING, false); activityJSON.put(AuthoringJsonTags.XCOORD, pos[0]); activityJSON.put(AuthoringJsonTags.YCOORD, pos[1]); - activityJSON.put(AuthoringJsonTags.ACTIVITY_TITLE, activityTitle != null ? activityTitle : "Gate"); - if ( activityDescription != null ) - activityJSON.put(AuthoringJsonTags.DESCRIPTION, activityDescription); + activityJSON.put(AuthoringJsonTags.ACTIVITY_TITLE, activityTitle != null ? activityTitle : "Gate"); + if (activityDescription != null) { + activityJSON.put(AuthoringJsonTags.DESCRIPTION, activityDescription); + } activityJSON.put(AuthoringJsonTags.ACTIVITY_CATEGORY_ID, Activity.CATEGORY_SYSTEM); activityJSON.put(AuthoringJsonTags.ACTIVITY_TYPE_ID, Activity.PERMISSION_GATE_ACTIVITY_TYPE); activityJSON.put(AuthoringJsonTags.GATE_ACTIVITY_LEVEL_ID, GateActivity.LEARNER_GATE_LEVEL); @@ -689,7 +694,7 @@ return createToolActivity(uiid, order, layoutCoords, toolSignature, toolIcon, toolContentID, contentFolderID, groupingUIID, parentUIID, parentActivityType, activityTitle, activityCategory, null); } - + protected ObjectNode createToolActivity(AtomicInteger uiid, int order, Integer[] layoutCoords, String toolSignature, String toolIcon, Long toolContentID, String contentFolderID, Integer groupingUIID, Integer parentUIID, Integer parentActivityType, String activityTitle, int activityCategory, String toolOutputDefinition) { @@ -721,7 +726,7 @@ } else { activityJSON.put(AuthoringJsonTags.APPLY_GROUPING, false); } - if ( toolOutputDefinition != null ) { + if (toolOutputDefinition != null) { activityJSON.put(AuthoringJsonTags.TOOL_OUTPUT_DEFINITION, toolOutputDefinition); } return activityJSON; @@ -777,7 +782,8 @@ * to be expanded. */ protected Long createAssessmentToolContent(UserDTO user, String title, String instructions, - String reflectionInstructions, boolean selectLeaderToolOutput, boolean enableNumbering, ArrayNode questions) throws IOException { + String reflectionInstructions, boolean selectLeaderToolOutput, boolean enableNumbering, ArrayNode questions) + throws IOException { ObjectNode toolContentJSON = createStandardToolContent(title, instructions, reflectionInstructions, null, null, user); @@ -990,7 +996,8 @@ * details of questions). Other fields are optional. */ protected Long createMCQToolContent(UserDTO user, String title, String instructions, - boolean useSelectLeaderToolOuput, boolean enableConfidenceLevel, boolean prefixAnswersWithLetters, ArrayNode questions) throws IOException { + boolean useSelectLeaderToolOuput, boolean enableConfidenceLevel, boolean prefixAnswersWithLetters, + ArrayNode questions) throws IOException { ObjectNode toolContentJSON = createStandardToolContent(title, instructions, null, null, null, null); toolContentJSON.put(RestTags.USE_SELECT_LEADER_TOOL_OUTPUT, useSelectLeaderToolOuput); @@ -1198,8 +1205,7 @@ * loginName; */ protected Long createSubmitToolContent(UserDTO user, String title, String instructions, boolean lockWhenFinished, - Boolean limitUpload, Integer limitUploadNumber, String reflectionInstructions) - throws IOException { + Boolean limitUpload, Integer limitUploadNumber, String reflectionInstructions) throws IOException { ObjectNode toolContentJSON = createStandardToolContent(title, instructions, reflectionInstructions, lockWhenFinished, null, user); @@ -1366,11 +1372,12 @@ } - @RequestMapping("/importQTI") + @RequestMapping("/importQTI") public String importAssessmentQTI(HttpServletRequest request) throws UnsupportedEncodingException { String contentFolderID = WebUtil.readStrParam(request, "contentFolderID"); String templatePage = WebUtil.readStrParam(request, "templatePage"); - List updatedQuestions = preprocessQuestions(QuestionParser.parseQuestionChoiceForm(request), contentFolderID); + List updatedQuestions = preprocessQuestions(QuestionParser.parseQuestionChoiceForm(request), + contentFolderID); request.setAttribute("questions", updatedQuestions); request.setAttribute("questionNumber", WebUtil.readIntParam(request, "questionNumber")); request.setAttribute("numQuestionsFieldname", WebUtil.readStrParam(request, "numQuestionsFieldname")); @@ -1380,9 +1387,9 @@ private List preprocessQuestions(Question[] questions, String contentFolderID) { - List assessments = new ArrayList(questions.length); + List assessments = new ArrayList<>(questions.length); - // Processing based on QTIUtil from the Assessment tool + // Processing based on QTIUtil from the Assessment tool for (Question question : questions) { Assessment assessment = new Assessment(); @@ -1395,6 +1402,7 @@ assessment.setText(QuestionParser.processHTMLField(question.getText(), false, contentFolderID, question.getResourcesFolderPath())); assessment.setTitle(question.getTitle()); + assessment.setUuid(question.getQbUUID()); if (isMultipleChoice) { assessment.setType(Assessment.ASSESSMENT_QUESTION_TYPE_MULTIPLE_CHOICE); @@ -1463,7 +1471,7 @@ } else { newAnswer.setGrade(0F); } - + assessment.getAnswers().add(newAnswer); } } @@ -1476,7 +1484,7 @@ return assessments; } - + /** * Specialised call to create a new question & options for the surveys tab. Returns a fragment of HTML * which sets up a new CKEditor. Works with both mcquestion.jsp & surveyquestion.jsp. The template's @@ -1558,10 +1566,10 @@ Integer questionNumber = WebUtil.readIntParam(request, "questionNumber", true); Integer delete = WebUtil.readIntParam(request, "optionNumber"); - + boolean useAssessmentVersion = WebUtil.readBooleanParam(request, "assess", false); - String containingDivName = WebUtil.readStrParam(request, "containingDivName", true); - String prefixParam = containingDivName != null ? containingDivName + "assmcq" : "question"; + String containingDivName = WebUtil.readStrParam(request, "containingDivName", true); + String prefixParam = containingDivName != null ? containingDivName + "assmcq" : "question"; TreeMap optionsMap = getOptions(request, questionNumber, prefixParam); optionsMap.remove(delete); // reorder the displayOrder and setup the return value @@ -1593,8 +1601,8 @@ } boolean useAssessmentVersion = WebUtil.readBooleanParam(request, "assess", false); - String containingDivName = WebUtil.readStrParam(request, "containingDivName", true); - String prefixParam = containingDivName != null ? containingDivName + "assmcq" : "question"; + String containingDivName = WebUtil.readStrParam(request, "containingDivName", true); + String prefixParam = containingDivName != null ? containingDivName + "assmcq" : "question"; TreeMap optionsMap = getOptions(request, questionNumber, prefixParam); // reorder the options and setup the return value LinkedList