diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemMetadata.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemMetadata.java index d1075655b69ce76b2708dcaadb96b2950b46a400..7f205a853c107703428109e77c0960dc6ec46f2c 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemMetadata.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemMetadata.java @@ -256,11 +256,13 @@ public class AssessmentItemMetadata { //qti metadata QTIMetadataType qtiMetadata = metadata.getQtiMetadata(true); - if(qtiMetadata.getToolName() != null) { - editor = qtiMetadata.getToolName(); - } - if(qtiMetadata.getToolVersion() != null) { - editorVersion = qtiMetadata.getToolVersion(); + if(qtiMetadata != null) { + if(qtiMetadata.getToolName() != null) { + editor = qtiMetadata.getToolName(); + } + if(qtiMetadata.getToolVersion() != null) { + editorVersion = qtiMetadata.getToolVersion(); + } } //openolat metadata diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java b/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java index 1ade128960c01bf9cb7464d34a0f1717fe26cfe8..905a3f5bda7c679412589c7d6ded602f0916ec05 100644 --- a/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java +++ b/src/main/java/org/olat/ims/qti21/pool/QTI21ExportProcessor.java @@ -201,9 +201,10 @@ public class QTI21ExportProcessor { assessmentItem.setIdentifier(QTI21QuestionType.generateNewIdentifier(assessmentItem.getIdentifier())); //save the item in its own container - File container = new File(directory, qitem.getKey().toString()); - container.mkdirs(); - File newItemFile = new File(container, assessmentItem.getIdentifier() + ".xml"); + String container = qitem.getKey().toString(); + File containerDir = new File(directory, container); + containerDir.mkdirs(); + File newItemFile = new File(containerDir, assessmentItem.getIdentifier() + ".xml"); String newItemFilename = container + "/" + newItemFile.getName(); qtiService.persistAssessmentObject(newItemFile, assessmentItem); diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java index 7d9c5c4609f03402529a5439d8a6d9140f7d76d5..4fe2ef0e164948363ad6656dc6c01c0f03cd6fd7 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java @@ -110,6 +110,7 @@ import org.olat.ims.qti21.ui.editor.events.AssessmentItemEvent; import org.olat.ims.qti21.ui.editor.events.AssessmentSectionEvent; import org.olat.ims.qti21.ui.editor.events.AssessmentTestEvent; import org.olat.ims.qti21.ui.editor.events.AssessmentTestPartEvent; +import org.olat.imscp.xml.manifest.FileType; import org.olat.imscp.xml.manifest.ResourceType; import org.olat.modules.qpool.QuestionItemView; import org.olat.modules.qpool.ui.SelectItemController; @@ -653,6 +654,9 @@ public class AssessmentTestComposerController extends MainLayoutBasicController ManifestBuilder clonedManifestBuilder = ManifestBuilder.read(new File(unzippedDirRoot, "imsmanifest.xml")); ResourceType resource = getResourceType(clonedManifestBuilder, itemRef); ManifestMetadataBuilder metadata = clonedManifestBuilder.getMetadataBuilder(resource, true); + if(metadata == null) { + metadata = new ManifestMetadataBuilder();// not in imsmanifest.xml? + } File itemFile = new File(rootNode.getSystemId()); @@ -971,6 +975,7 @@ public class AssessmentTestComposerController extends MainLayoutBasicController if(sectionPart instanceof AssessmentItemRef) { AssessmentItemRef itemRef = (AssessmentItemRef)sectionPart; ResolvedAssessmentItem resolvedAssessmentItem = resolvedAssessmentTest.getResolvedAssessmentItem(itemRef); + checkAndFixAbsolutePath(itemRef); AssessmentItem assessmentItem = null; if(resolvedAssessmentItem != null) { @@ -999,7 +1004,56 @@ public class AssessmentTestComposerController extends MainLayoutBasicController } } + private void checkAndFixAbsolutePath(AssessmentItemRef itemRef) { + if(itemRef == null || itemRef.getHref() == null) return; + + String href = itemRef.getHref().toString(); + if(isAbsolutePath(href)) { + try { + String relativeHref = fixAbsolutePath(href); + itemRef.setHref(new URI(relativeHref)); + } catch (URISyntaxException e) { + logError("", e); + } + } + } + + private void checkAndFixAbsolutePath(ResourceType resource) { + if(resource == null) return; + + if(isAbsolutePath(resource.getHref())) { + resource.setHref(fixAbsolutePath(resource.getHref())); + + List<FileType> files = resource.getFile(); + if(files != null) { + for(FileType file:files) { + if(isAbsolutePath(file.getHref())) { + file.setHref(fixAbsolutePath(file.getHref())); + } + } + } + } + } + + /** + * It check if the path is absolute and in the form of a absolute within an openolat instance. + * @param href + * @return + */ + private boolean isAbsolutePath(String href) { + return href != null && href.startsWith("/") && href.contains("/bcroot/repository/") && href.contains("/_unzipped_/"); + } + + private String fixAbsolutePath(String href) { + int index = href.indexOf("/_unzipped_/") + ("/_unzipped_/").length(); + return href.substring(index); + } + private void doSaveManifest() { + List<ResourceType> resources = manifestBuilder.getResourceList(); + for(ResourceType resource:resources) { + checkAndFixAbsolutePath(resource); + } manifestBuilder.write(new File(unzippedDirRoot, "imsmanifest.xml")); }