Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -rbb09e59547fe7c584f105bee03af346a05dde411 -rc6d1e011ff92ac2a8b0581efa0982100101c70b7 Binary files differ Index: lams_central/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -ra43256ee6435f1cd14f46c235e4d507957a86a5b -rc6d1e011ff92ac2a8b0581efa0982100101c70b7 --- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision a43256ee6435f1cd14f46c235e4d507957a86a5b) +++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision c6d1e011ff92ac2a8b0581efa0982100101c70b7) @@ -395,7 +395,7 @@ label.tab.conditions.enable =Enable label.tab.conditions.dependencies.desc =Select a lesson that students will need to complete before they can see the lesson you are about to create. label.questions.file.title =Choose IMS QTI file -label.questions.file.missing =Please select a ZIP file with questions in IMS QTI format. +label.questions.file.missing =Please select a ZIP or XML file with questions in IMS QTI format. label.questions.choice.title =Choose questions label.questions.choice.select.all =Select all label.questions.choice.missing =Please check at least one question. Index: lams_central/src/java/org/lamsfoundation/lams/web/QuestionsAction.java =================================================================== diff -u -ra43256ee6435f1cd14f46c235e4d507957a86a5b -rc6d1e011ff92ac2a8b0581efa0982100101c70b7 --- lams_central/src/java/org/lamsfoundation/lams/web/QuestionsAction.java (.../QuestionsAction.java) (revision a43256ee6435f1cd14f46c235e4d507957a86a5b) +++ lams_central/src/java/org/lamsfoundation/lams/web/QuestionsAction.java (.../QuestionsAction.java) (revision c6d1e011ff92ac2a8b0581efa0982100101c70b7) @@ -43,7 +43,8 @@ String returnURL = null; String limitTypeParam = null; - InputStream packageFileStream = null; + InputStream uploadedFileStream = null; + String packageName = null; for (FileItem formField : formFields) { String fieldName = formField.getFieldName(); if ("returnURL".equals(fieldName)) { @@ -52,15 +53,16 @@ } else if ("limitType".equals(fieldName)) { limitTypeParam = formField.getString(); } else if ("file".equals(fieldName) && !StringUtils.isBlank(formField.getName())) { - packageFileStream = formField.getInputStream(); + packageName = formField.getName().toLowerCase(); + uploadedFileStream = formField.getInputStream(); } } request.setAttribute("returnURL", returnURL); request.setAttribute("limitType", limitTypeParam); // user did not choose a file - if (packageFileStream == null) { + if ((uploadedFileStream == null) || !(packageName.endsWith(".zip") || packageName.endsWith(".xml"))) { ActionMessages errors = new ActionMessages(); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("label.questions.file.missing")); request.setAttribute(Globals.ERROR_KEY, errors); @@ -74,7 +76,9 @@ Collections.addAll(limitType, limitTypeParam.split(",")); } - Question[] questions = QuestionParser.parseQTIPackage(packageFileStream, limitType); + Question[] questions = packageName.endsWith(".xml") ? QuestionParser + .parseQTIFile(uploadedFileStream, limitType) : QuestionParser.parseQTIPackage(uploadedFileStream, + limitType); request.setAttribute("questions", questions); return mapping.findForward("questionChoice"); Index: lams_common/src/java/org/lamsfoundation/lams/questions/QuestionParser.java =================================================================== diff -u -ra43256ee6435f1cd14f46c235e4d507957a86a5b -rc6d1e011ff92ac2a8b0581efa0982100101c70b7 --- lams_common/src/java/org/lamsfoundation/lams/questions/QuestionParser.java (.../QuestionParser.java) (revision a43256ee6435f1cd14f46c235e4d507957a86a5b) +++ lams_common/src/java/org/lamsfoundation/lams/questions/QuestionParser.java (.../QuestionParser.java) (revision c6d1e011ff92ac2a8b0581efa0982100101c70b7) @@ -87,14 +87,21 @@ } else { // extract from every XML file; usually there is just one for (File resourceFile : resourceFiles) { - Question[] fileQuestions = QuestionParser.parseQTIFile(resourceFile, limitType); + FileInputStream xmlFileStream = new FileInputStream(resourceFile); + Question[] fileQuestions = null; + try { + fileQuestions = QuestionParser.parseQTIFile(xmlFileStream, limitType); + } finally { + xmlFileStream.close(); + } if (fileQuestions != null) { Collections.addAll(result, fileQuestions); } } } } finally { // clean up + packageFileStream.close(); ZipFileUtil.deleteDirectory(tempPackageDirPath); } @@ -104,11 +111,11 @@ /** * Extracts questions from IMS QTI xml file. */ - public static Question[] parseQTIFile(File xmlFile, Set limitType) throws ParserConfigurationException, - SAXException, IOException { + public static Question[] parseQTIFile(InputStream xmlFileStream, Set limitType) + throws ParserConfigurationException, SAXException, IOException { List result = new ArrayList(); DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document doc = docBuilder.parse(xmlFile); + Document doc = docBuilder.parse(xmlFileStream); NodeList questionItems = doc.getElementsByTagName("item"); // yes, a label here for convenience