Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java =================================================================== diff -u -rda30e197f54c6bc1c0d6d9d5dbcdde3c4632d329 -r80ab947256f1314103a88c68432755741615271b --- lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java (.../EditQbQuestionController.java) (revision da30e197f54c6bc1c0d6d9d5dbcdde3c4632d329) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java (.../EditQbQuestionController.java) (revision 80ab947256f1314103a88c68432755741615271b) @@ -5,11 +5,9 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.Optional; import java.util.TreeSet; import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -64,7 +62,7 @@ //TODO think about where do we need to get ContentFolderID, and whether it's a good idea to generate a new one each time String contentFolderID = FileUtil.generateUniqueContentFolderID(); - + QbQuestionForm questionForm = new QbQuestionForm(); //we need to set form as a request attribute, as long as we use jsps from another context from the Assessment tool request.setAttribute("assessmentQuestionForm", questionForm); @@ -99,12 +97,12 @@ Integer type = NumberUtils.toInt(request.getParameter(QbConstants.ATTR_QUESTION_TYPE)); // sessionMap.put(QbConstants.ATTR_QUESTION_TYPE, type); request.setAttribute(AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); - - String jspPageName = getAuthoringJspByQuestionType(type); + + String jspPageName = EditQbQuestionController.getAuthoringJspByQuestionType(type); forwardToAssessmentJsp(jspPageName, request, response); return null; } - + /** * Display edit page for existed assessment question. */ @@ -121,17 +119,17 @@ //we need to set form as a request attribute, as long as we use jsps from another context from the Assessment tool request.setAttribute("assessmentQuestionForm", questionForm); QbUtils.fillFormWithQbQuestion(qbQuestion, questionForm, request); - + //store uid as displayOrder in order to use it later during question saving questionForm.setDisplayOrder(qbQuestionUid.intValue()); - + //TODO think about where do we need to get ContentFolderID, and whether it's a good idea to generate a new one each time String contentFolderID = FileUtil.generateUniqueContentFolderID(); questionForm.setContentFolderID(contentFolderID); request.setAttribute(AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); - - String jspPageName = getAuthoringJspByQuestionType(qbQuestion.getType()); - forwardToAssessmentJsp(jspPageName, request, response); + + String jspPageName = EditQbQuestionController.getAuthoringJspByQuestionType(qbQuestion.getType()); + forwardToAssessmentJsp(jspPageName, request, response); return null; } @@ -140,7 +138,8 @@ * HttpSession AssessmentQuestionList. Notice, this save is not persist them into database, just save * HttpSession temporarily. Only they will be persist when the entire authoring page is being * persisted. - * @throws IOException + * + * @throws IOException */ @RequestMapping("/saveOrUpdateQuestion") @ResponseBody @@ -149,18 +148,18 @@ //find according question QbQuestion qbQuestion = null; Long oldQuestionUid = null; - + // add - if (questionForm.getDisplayOrder() == -1) { + if (questionForm.getDisplayOrder() == -1) { qbQuestion = new QbQuestion(); qbQuestion.setType(questionForm.getQuestionType()); - - // edit + + // edit } else { oldQuestionUid = Long.valueOf(questionForm.getDisplayOrder()); qbQuestion = qbService.getQbQuestionByUid(oldQuestionUid); } - + boolean IS_AUTHORING_RESTRICTED = false; int isQbQuestionModified = QbUtils.extractFormToQbQuestion(qbQuestion, questionForm, request, qbService, IS_AUTHORING_RESTRICTED); @@ -178,48 +177,49 @@ qbQuestion = qbQuestion.clone(); qbQuestion.clearID(); qbQuestion.setVersion(1); - qbQuestion.setQuestionId(qbService.getMaxQuestionId()+1); + qbQuestion.setQuestionId(qbService.getMaxQuestionId() + 1); qbQuestion.setCreateDate(new Date()); - + } break; } boolean belongsToNoCollection = qbQuestion.getUid() == null; userManagementService.save(qbQuestion); - + //in case of new question - add it to specified collection if (belongsToNoCollection) { Long collectionUid = questionForm.getCollectionUid(); //try to get collection from the old question if (collectionUid != null && collectionUid.equals(-1L)) { - Collection existingCollections = qbService.getQuestionCollections(oldQuestionUid); + Collection existingCollections = qbService.getQuestionCollectionsByUid(oldQuestionUid); collectionUid = existingCollections.stream().findFirst().map(collection -> collection.getUid()) .orElse(null); } if (collectionUid != null && !collectionUid.equals(-1L)) { - qbService.addQuestionToCollection(collectionUid, qbQuestion.getUid(), false); + qbService.addQuestionToCollection(collectionUid, qbQuestion.getQuestionId(), false); } } - + // add question case - return nothing if (questionForm.getDisplayOrder() == -1) { return null; - - // edit question case - return question's uid + + // edit question case - return question's uid } else { response.setContentType("text/plain"); response.setCharacterEncoding("UTF-8"); return qbQuestion.getUid().toString(); } } - + /** * Ajax call, will add one more input line for new resource item instruction. */ @RequestMapping("/addOption") - public String addOption(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + public String addOption(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { TreeSet optionList = QbUtils.getOptionsFromRequest(qbService, request, false); QbOption option = new QbOption(); int maxSeq = 1; @@ -243,7 +243,8 @@ * Ajax call, will add one more input line for new Unit. */ @RequestMapping("/newUnit") - public String newUnit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + public String newUnit(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { TreeSet unitList = QbUtils.getUnitsFromRequest(qbService, request, false); QbQuestionUnit unit = new QbQuestionUnit(); int maxSeq = 1; @@ -258,7 +259,7 @@ forwardToAssessmentJsp("unitlist.jsp", request, response); return null; } - + /** * Get back jsp name. */ @@ -297,14 +298,16 @@ } /** - * Forwards to the specified jsp page from Assessment tool. + * Forwards to the specified jsp page from Assessment tool. */ private void forwardToAssessmentJsp(String jspPageName, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String serverURLContextPath = Configuration.get(ConfigurationKeys.SERVER_URL_CONTEXT_PATH); serverURLContextPath = serverURLContextPath.startsWith("/") ? serverURLContextPath : "/" + serverURLContextPath; serverURLContextPath += serverURLContextPath.endsWith("/") ? "" : "/"; - applicationcontext.getServletContext().getContext(serverURLContextPath + "tool/" + CommonConstants.TOOL_SIGNATURE_ASSESSMENT) - .getRequestDispatcher("/pages/authoring/parts/" + jspPageName +"?lessonID=1").forward(request, response); + applicationcontext.getServletContext() + .getContext(serverURLContextPath + "tool/" + CommonConstants.TOOL_SIGNATURE_ASSESSMENT) + .getRequestDispatcher("/pages/authoring/parts/" + jspPageName + "?lessonID=1") + .forward(request, response); } } Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/ImsQtiController.java =================================================================== diff -u -r28f74fe44f679cfe7305cb1ddf42150f2de4c52c -r80ab947256f1314103a88c68432755741615271b --- lams_central/src/java/org/lamsfoundation/lams/web/qb/ImsQtiController.java (.../ImsQtiController.java) (revision 28f74fe44f679cfe7305cb1ddf42150f2de4c52c) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/ImsQtiController.java (.../ImsQtiController.java) (revision 80ab947256f1314103a88c68432755741615271b) @@ -31,7 +31,7 @@ /** * Exports and imports IMS QTI questions. - * + * * @author Andrey Balan */ @Controller @@ -45,10 +45,10 @@ @Autowired private IQbService qbService; - + @Autowired private IUserManagementService userManagementService; - + /** * Parses questions extracted from IMS QTI file and adds them as new QB questions. */ @@ -57,15 +57,15 @@ public void saveQTI(HttpServletRequest request, @RequestParam long collectionUid, @RequestParam String contentFolderID) throws UnsupportedEncodingException { int questionId = qbService.getMaxQuestionId(); - + Question[] questions = QuestionParser.parseQuestionChoiceForm(request); for (Question question : questions) { QbQuestion qbQuestion = new QbQuestion(); qbQuestion.setName(question.getTitle()); qbQuestion.setDescription(QuestionParser.processHTMLField(question.getText(), false, contentFolderID, question.getResourcesFolderPath())); - qbQuestion.setFeedback(QuestionParser.processHTMLField(question.getFeedback(), false, - contentFolderID, question.getResourcesFolderPath())); + qbQuestion.setFeedback(QuestionParser.processHTMLField(question.getFeedback(), false, contentFolderID, + question.getResourcesFolderPath())); qbQuestion.setPenaltyFactor(0); qbQuestion.setQuestionId(++questionId); @@ -298,15 +298,15 @@ qbQuestion.setMaxMark(questionMark); userManagementService.save(qbQuestion); - - qbService.addQuestionToCollection(collectionUid, qbQuestion.getUid(), false); - + + qbService.addQuestionToCollection(collectionUid, qbQuestion.getQuestionId(), false); + if (log.isDebugEnabled()) { log.debug("Imported QTI question. Name: " + qbQuestion.getName() + ", uid: " + qbQuestion.getUid()); } } } - + /** * Exports QB question as IMS QTI package. */ @@ -390,8 +390,7 @@ answer.setText(assessmentAnswer.getName()); answer.setScore( - isCorrectAnswer ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() - : 0); + isCorrectAnswer ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); answer.setFeedback(isCorrectAnswer ? qbQuestion.getFeedbackOnCorrect() : qbQuestion.getFeedbackOnIncorrect()); @@ -422,18 +421,16 @@ // true/false question is basically the same for QTI, just with special answers Answer trueAnswer = new Answer(); trueAnswer.setText("True"); - trueAnswer.setScore( - isTrueCorrect ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); - trueAnswer.setFeedback(isTrueCorrect ? qbQuestion.getFeedbackOnCorrect() - : qbQuestion.getFeedbackOnIncorrect()); + trueAnswer.setScore(isTrueCorrect ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); + trueAnswer.setFeedback( + isTrueCorrect ? qbQuestion.getFeedbackOnCorrect() : qbQuestion.getFeedbackOnIncorrect()); answers.add(trueAnswer); Answer falseAnswer = new Answer(); falseAnswer.setText("False"); - falseAnswer.setScore( - !isTrueCorrect ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); - falseAnswer.setFeedback(!isTrueCorrect ? qbQuestion.getFeedbackOnCorrect() - : qbQuestion.getFeedbackOnIncorrect()); + falseAnswer.setScore(!isTrueCorrect ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); + falseAnswer.setFeedback( + !isTrueCorrect ? qbQuestion.getFeedbackOnCorrect() : qbQuestion.getFeedbackOnIncorrect()); answers.add(falseAnswer); break; @@ -476,8 +473,7 @@ boolean isCorrectAnswer = assessmentAnswer.isCorrect(); answer.setText(assessmentAnswer.getName()); - answer.setScore( - isCorrectAnswer ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); + answer.setScore(isCorrectAnswer ? Integer.valueOf(qbQuestion.getMaxMark()).floatValue() : 0); answer.setFeedback(isCorrectAnswer ? qbQuestion.getFeedbackOnCorrect() : qbQuestion.getFeedbackOnIncorrect()); Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java =================================================================== diff -u -r26ce32081def8b8d0a0e38f513100920d33dbef1 -r80ab947256f1314103a88c68432755741615271b --- lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java (.../QbCollectionController.java) (revision 26ce32081def8b8d0a0e38f513100920d33dbef1) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/QbCollectionController.java (.../QbCollectionController.java) (revision 80ab947256f1314103a88c68432755741615271b) @@ -139,9 +139,11 @@ rowElement.setAttribute(CommonConstants.ELEMENT_ID, uid); // the last cell is for creating stats button - String usage = showUsage ? String.valueOf(qbService.getCountQuestionActivities(question.getUid())) + String usage = showUsage + ? String.valueOf(qbService.getCountQuestionActivitiesByQuestionId(question.getQuestionId())) : null; - String[] data = { uid, WebUtil.removeHTMLtags(question.getName()).trim(), question.getType().toString(), + String[] data = { question.getQuestionId().toString(), + WebUtil.removeHTMLtags(question.getName()).trim(), question.getType().toString(), question.getVersion().toString(), usage, uid }; for (String cell : data) { @@ -168,18 +170,18 @@ @RequestMapping("/removeCollectionQuestion") @ResponseBody - public void removeCollectionQuestion(@RequestParam long collectionUid, @RequestParam long qbQuestionUid) { - qbService.removeQuestionFromCollection(collectionUid, qbQuestionUid); + public void removeCollectionQuestion(@RequestParam long collectionUid, @RequestParam int qbQuestionId) { + qbService.removeQuestionFromCollectionByQuestionId(collectionUid, qbQuestionId); } @RequestMapping("/addCollectionQuestion") @ResponseBody public void addCollectionQuestion(@RequestParam long targetCollectionUid, @RequestParam boolean copy, - @RequestParam long qbQuestionUid) { + @RequestParam int qbQuestionId) { if (!Configuration.getAsBoolean(ConfigurationKeys.QB_COLLECTIONS_TRANSFER_ALLOW)) { throw new SecurityException("Transfering questions between collections is disabled"); } - qbService.addQuestionToCollection(targetCollectionUid, qbQuestionUid, copy); + qbService.addQuestionToCollection(targetCollectionUid, qbQuestionId, copy); } @RequestMapping("/addCollection") Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/QbStatsController.java =================================================================== diff -u -rca75b4c508f9d195245818cdd4574f335e75d9c6 -r80ab947256f1314103a88c68432755741615271b --- lams_central/src/java/org/lamsfoundation/lams/web/qb/QbStatsController.java (.../QbStatsController.java) (revision ca75b4c508f9d195245818cdd4574f335e75d9c6) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/QbStatsController.java (.../QbStatsController.java) (revision 80ab947256f1314103a88c68432755741615271b) @@ -60,7 +60,7 @@ QbStatsDTO stats = qbService.getQbQuestionStats(qbQuestionUid); model.addAttribute("stats", stats); - Collection existingCollections = qbService.getQuestionCollections(qbQuestionUid); + Collection existingCollections = qbService.getQuestionCollectionsByUid(qbQuestionUid); model.addAttribute("existingCollections", existingCollections); Integer userId = getUserId(); @@ -71,7 +71,7 @@ boolean permanentRemove = existingCollections.size() <= 1; model.addAttribute("permanentRemove", permanentRemove); model.addAttribute("permanentRemovePossible", - permanentRemove ? qbService.removeQuestionPossible(qbQuestionUid) : false); + permanentRemove ? qbService.removeQuestionPossibleByUid(qbQuestionUid) : false); model.addAttribute("transferAllowed", Configuration.getAsBoolean(ConfigurationKeys.QB_COLLECTIONS_TRANSFER_ALLOW)); Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/XmlQuestionsController.java =================================================================== diff -u -r1b530a88ae6d3a1e553081b3d56117ec5ad3622a -r80ab947256f1314103a88c68432755741615271b --- lams_central/src/java/org/lamsfoundation/lams/web/qb/XmlQuestionsController.java (.../XmlQuestionsController.java) (revision 1b530a88ae6d3a1e553081b3d56117ec5ad3622a) +++ lams_central/src/java/org/lamsfoundation/lams/web/qb/XmlQuestionsController.java (.../XmlQuestionsController.java) (revision 80ab947256f1314103a88c68432755741615271b) @@ -4,37 +4,22 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Date; -import java.util.LinkedList; import java.util.List; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; import org.lamsfoundation.lams.qb.model.QbCollection; -import org.lamsfoundation.lams.qb.model.QbOption; import org.lamsfoundation.lams.qb.model.QbQuestion; import org.lamsfoundation.lams.qb.service.IQbService; -import org.lamsfoundation.lams.questions.Answer; -import org.lamsfoundation.lams.questions.Question; -import org.lamsfoundation.lams.questions.QuestionExporter; -import org.lamsfoundation.lams.questions.QuestionParser; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.FileUtil; -import org.lamsfoundation.lams.util.MessageService; -import org.lamsfoundation.lams.util.WebUtil; -import org.lamsfoundation.lams.web.util.SessionMap; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -47,7 +32,7 @@ /** * Exports and imports questions from the given collection in XML format. - * + * * @author Andrey Balan */ @Controller @@ -57,7 +42,7 @@ @Autowired private IQbService qbService; - + @Autowired private IUserManagementService userManagementService; @@ -78,7 +63,7 @@ public void importQuestionsXml(@RequestParam("UPLOAD_FILE") MultipartFile file, HttpServletRequest request, @RequestParam long collectionUid) throws ServletException { int questionId = qbService.getMaxQuestionId(); - + List toolsErrorMsgs = new ArrayList<>(); try { String uploadPath = FileUtil.createTempDirectory("_uploaded_2questions_xml"); @@ -96,15 +81,15 @@ // import learning design String fullFilePath = destinationFile.getAbsolutePath();// FileUtil.getFullPath(learningDesignPath, - // ExportToolContentService.LEARNING_DESIGN_FILE_NAME); + // ExportToolContentService.LEARNING_DESIGN_FILE_NAME); List questions = (List) FileUtil.getObjectFromXML(null, fullFilePath); if (questions != null) { for (QbQuestion qbQuestion : questions) { qbQuestion.setQuestionId(++questionId); qbQuestion.setCreateDate(new Date()); userManagementService.save(qbQuestion); - qbService.addQuestionToCollection(collectionUid, qbQuestion.getUid(), false); + qbService.addQuestionToCollection(collectionUid, qbQuestion.getQuestionId(), false); if (log.isDebugEnabled()) { log.debug("Imported XML question. Name: " + qbQuestion.getName() + ", uid: " @@ -127,13 +112,14 @@ * Exports xml format questions from question collection. */ @RequestMapping("/exportQuestionsXml") - public void exportQuestionsXml(HttpServletRequest request, HttpServletResponse response, @RequestParam long collectionUid) { + public void exportQuestionsXml(HttpServletRequest request, HttpServletResponse response, + @RequestParam long collectionUid) { List qbQuestions = qbService.getCollectionQuestions(collectionUid); String errors = null; try { ArrayList questionsToExport = new ArrayList<>(); for (QbQuestion qbQuestion : qbQuestions) { - QbQuestion clonedQuestion = (QbQuestion) qbQuestion.clone(); + QbQuestion clonedQuestion = qbQuestion.clone(); clonedQuestion.clearID(); clonedQuestion.setVersion(1); questionsToExport.add(clonedQuestion); Index: lams_central/web/qb/collection.jsp =================================================================== diff -u -r26ce32081def8b8d0a0e38f513100920d33dbef1 -r80ab947256f1314103a88c68432755741615271b --- lams_central/web/qb/collection.jsp (.../collection.jsp) (revision 26ce32081def8b8d0a0e38f513100920d33dbef1) +++ lams_central/web/qb/collection.jsp (.../collection.jsp) (revision 80ab947256f1314103a88c68432755741615271b) @@ -111,7 +111,7 @@ "Actions" ], colModel:[ - {name:'id', index:'uid', sortable:true, hidden:true, width: 10}, + {name:'id', index:'uid', sortable:true, hidden:false, width: 10}, {name:'name', index:'name', sortable:true, search:true, autoencode:true, formatter: questionNameFormatter}, {name:'questionType', index:'questionType', width:0, hidden: true}, {name:'questionVersion', index:'questionVersion', width:0, hidden: true}, Index: lams_central/web/qb/stats.jsp =================================================================== diff -u -r57a3647e9f7b79d5fe02d9727194311b4930d867 -r80ab947256f1314103a88c68432755741615271b --- lams_central/web/qb/stats.jsp (.../stats.jsp) (revision 57a3647e9f7b79d5fe02d9727194311b4930d867) +++ lams_central/web/qb/stats.jsp (.../stats.jsp) (revision 80ab947256f1314103a88c68432755741615271b) @@ -59,10 +59,13 @@