Skip to content
Snippets Groups Projects
Commit e89221b3 authored by srosse's avatar srosse
Browse files

OO-3120: enhance handling of metadata in QTI 2.1 (import / export)

parent 43ab04a4
No related branches found
No related tags found
No related merge requests found
...@@ -2087,7 +2087,7 @@ ...@@ -2087,7 +2087,7 @@
<dependency> <dependency>
<groupId>org.openolat.imscp</groupId> <groupId>org.openolat.imscp</groupId>
<artifactId>manifest</artifactId> <artifactId>manifest</artifactId>
<version>1.4.1</version> <version>1.4.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.rometools</groupId> <groupId>com.rometools</groupId>
......
...@@ -45,6 +45,10 @@ public class AssessmentItemMetadata { ...@@ -45,6 +45,10 @@ public class AssessmentItemMetadata {
private String license; private String license;
private String editor; private String editor;
private String editorVersion; private String editorVersion;
private String topic;
private String creator;
private String assessmentType;
private String additionalInformations;
private int numOfAnswerAlternatives; private int numOfAnswerAlternatives;
private BigDecimal difficulty; private BigDecimal difficulty;
private BigDecimal differentiation; private BigDecimal differentiation;
...@@ -191,6 +195,38 @@ public class AssessmentItemMetadata { ...@@ -191,6 +195,38 @@ public class AssessmentItemMetadata {
this.hasError = hasError; this.hasError = hasError;
} }
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public String getAssessmentType() {
return assessmentType;
}
public void setAssessmentType(String assessmentType) {
this.assessmentType = assessmentType;
}
public String getAdditionalInformations() {
return additionalInformations;
}
public void setAdditionalInformations(String additionalInformations) {
this.additionalInformations = additionalInformations;
}
public void toBuilder(ManifestMetadataBuilder metadata, Locale locale) { public void toBuilder(ManifestMetadataBuilder metadata, Locale locale) {
if(getQuestionType() != null) { if(getQuestionType() != null) {
metadata.setOpenOLATMetadataQuestionType(getQuestionType().getPrefix()); metadata.setOpenOLATMetadataQuestionType(getQuestionType().getPrefix());
...@@ -243,19 +279,30 @@ public class AssessmentItemMetadata { ...@@ -243,19 +279,30 @@ public class AssessmentItemMetadata {
if(numOfAnswerAlternatives >= 0) { if(numOfAnswerAlternatives >= 0) {
metadata.setOpenOLATMetadataDistractors(numOfAnswerAlternatives); metadata.setOpenOLATMetadataDistractors(numOfAnswerAlternatives);
} }
metadata.setOpenOLATMetadataCreator(creator);
metadata.setOpenOLATMetadataTopic(topic);
metadata.setOpenOLATMetadataAssessmentType(assessmentType);
metadata.setOpenOLATMetadataAdditionalInformations(additionalInformations);
} }
public void fromBuilder(ManifestMetadataBuilder metadata) { public void fromBuilder(ManifestMetadataBuilder metadata) {
// general // general
keywords = metadata.getGeneralKeywords(); keywords = metadata.getGeneralKeywords();
coverage = metadata.getCoverage();
//educational
EducationalType educational = metadata.getEducational(false); EducationalType educational = metadata.getEducational(false);
if(educational != null) { if(educational != null) {
level = metadata.getEducationContext(); level = metadata.getEducationContext();
} }
typicalLearningTime = metadata.getEducationalLearningTime();
//taxonomy
taxonomyPath = metadata.getClassificationTaxonomy(); taxonomyPath = metadata.getClassificationTaxonomy();
//rights
license = metadata.getLicense();
//qti metadata //qti metadata
QTIMetadataType qtiMetadata = metadata.getQtiMetadata(true); QTIMetadataType qtiMetadata = metadata.getQtiMetadata(true);
if(qtiMetadata != null) { if(qtiMetadata != null) {
...@@ -282,6 +329,18 @@ public class AssessmentItemMetadata { ...@@ -282,6 +329,18 @@ public class AssessmentItemMetadata {
if(openolatMetadata.getDistractors() != null) { if(openolatMetadata.getDistractors() != null) {
numOfAnswerAlternatives = openolatMetadata.getDistractors().intValue(); numOfAnswerAlternatives = openolatMetadata.getDistractors().intValue();
} }
if(openolatMetadata.getTopic() != null) {
topic = openolatMetadata.getTopic();
}
if(openolatMetadata.getAssessmentType() != null) {
assessmentType = openolatMetadata.getAssessmentType();
}
if(openolatMetadata.getCreator() != null) {
creator = openolatMetadata.getCreator();
}
if(openolatMetadata.getAdditionalInformations() != null) {
additionalInformations = openolatMetadata.getAdditionalInformations();
}
} }
} }
} }
\ No newline at end of file
...@@ -303,21 +303,30 @@ public class ManifestMetadataBuilder { ...@@ -303,21 +303,30 @@ public class ManifestMetadataBuilder {
} }
} }
public void setLicense(String license) { public String getLicense() {
RightsType rights = getRights(true); RightsType rights = getRights(true);
if(rights != null) { if(rights != null) {
CopyrightandotherrestrictionsType type = getFromAny(CopyrightandotherrestrictionsType.class, rights.getContent()); CopyrightandotherrestrictionsType type = getFromAny(CopyrightandotherrestrictionsType.class, rights.getContent());
if(type == null) { if(type != null && type.getValue() != null && type.getValue().getLangstring() != null) {
type = mdObjectFactory.createCopyrightandotherrestrictionsType(); return type.getValue().getLangstring().getValue();
rights.getContent().add(mdObjectFactory.createCopyrightandotherrestrictions(type)); }
}
SourceType sourceType = mdObjectFactory.createSourceType();
sourceType.setLangstring(createString("https://www.openolat.org", "en"));
ValueType valueType = mdObjectFactory.createValueType();
valueType.setLangstring(createString(license, "en"));
type.setSource(sourceType);
type.setValue(valueType);
} }
return null;
}
public void setLicense(String license) {
RightsType rights = getRights(true);
CopyrightandotherrestrictionsType type = getFromAny(CopyrightandotherrestrictionsType.class, rights.getContent());
if(type == null) {
type = mdObjectFactory.createCopyrightandotherrestrictionsType();
rights.getContent().add(mdObjectFactory.createCopyrightandotherrestrictions(type));
}
SourceType sourceType = mdObjectFactory.createSourceType();
sourceType.setLangstring(createString("https://www.openolat.org", "en"));
ValueType valueType = mdObjectFactory.createValueType();
valueType.setLangstring(createString(license, "en"));
type.setSource(sourceType);
type.setValue(valueType);
} }
public String getClassificationTaxonomy() { public String getClassificationTaxonomy() {
...@@ -684,6 +693,33 @@ public class ManifestMetadataBuilder { ...@@ -684,6 +693,33 @@ public class ManifestMetadataBuilder {
} }
} }
public String getOpenOLATMetadataCreator() {
OpenOLATMetadataType ooMetadata = getOpenOLATMetadata(false);
return ooMetadata == null ? null : ooMetadata.getCreator();
}
public void setOpenOLATMetadataCreator(String creator) {
getOpenOLATMetadata(true).setCreator(creator);
}
public String getOpenOLATMetadataTopic() {
OpenOLATMetadataType ooMetadata = getOpenOLATMetadata(false);
return ooMetadata == null ? null : ooMetadata.getTopic();
}
public void setOpenOLATMetadataTopic(String topic) {
getOpenOLATMetadata(true).setTopic(topic);
}
public String getOpenOLATMetadataAdditionalInformations() {
OpenOLATMetadataType ooMetadata = getOpenOLATMetadata(false);
return ooMetadata == null ? null : ooMetadata.getAdditionalInformations();
}
public void setOpenOLATMetadataAdditionalInformations(String informations) {
getOpenOLATMetadata(true).setAdditionalInformations(informations);
}
/** /**
* Return the qti metadata if it exists or if specified, create * Return the qti metadata if it exists or if specified, create
* one and append it to the metadata of the resource. * one and append it to the metadata of the resource.
...@@ -864,5 +900,8 @@ public class ManifestMetadataBuilder { ...@@ -864,5 +900,8 @@ public class ManifestMetadataBuilder {
setOpenOLATMetadataStandardDeviation(item.getStdevDifficulty()); setOpenOLATMetadataStandardDeviation(item.getStdevDifficulty());
setOpenOLATMetadataUsage(item.getUsage()); setOpenOLATMetadataUsage(item.getUsage());
setOpenOLATMetadataAssessmentType(item.getAssessmentType()); setOpenOLATMetadataAssessmentType(item.getAssessmentType());
setOpenOLATMetadataCreator(item.getCreator());
setOpenOLATMetadataTopic(item.getTopic());
setOpenOLATMetadataAdditionalInformations(item.getAdditionalInformations());
} }
} }
...@@ -130,9 +130,9 @@ public class QTI21ImportProcessor { ...@@ -130,9 +130,9 @@ public class QTI21ImportProcessor {
List<Path> imsmanifests = visitor.getImsmanifestFiles(); List<Path> imsmanifests = visitor.getImsmanifestFiles();
for(Path imsmanifest:imsmanifests) { for(Path imsmanifest:imsmanifests) {
InputStream in = Files.newInputStream(imsmanifest); InputStream in = Files.newInputStream(imsmanifest);
ManifestBuilder manifestBuilder = ManifestBuilder.read(new ShieldInputStream(in)); ManifestBuilder manifestBuilder = ManifestBuilder.read(new ShieldInputStream(in));
List<ResourceType> resources = manifestBuilder.getResourceList(); List<ResourceType> resources = manifestBuilder.getResourceList();
for(ResourceType resource:resources) { for(ResourceType resource:resources) {
ManifestMetadataBuilder metadataBuilder = manifestBuilder.getMetadataBuilder(resource, true); ManifestMetadataBuilder metadataBuilder = manifestBuilder.getMetadataBuilder(resource, true);
QuestionItem qitem = processResource(resource, imsmanifest, metadataBuilder); QuestionItem qitem = processResource(resource, imsmanifest, metadataBuilder);
...@@ -288,12 +288,6 @@ public class QTI21ImportProcessor { ...@@ -288,12 +288,6 @@ public class QTI21ImportProcessor {
QItemType defType = convertType(assessmentItem); QItemType defType = convertType(assessmentItem);
poolItem.setType(defType); poolItem.setType(defType);
} }
/*if(docInfos != null) {
processSidecarMetadata(poolItem, docInfos);
}*/
if(metadata != null) {
//processItemMetadata(poolItem, metadata);
}
questionItemDao.persist(owner, poolItem); questionItemDao.persist(owner, poolItem);
return poolItem; return poolItem;
} }
...@@ -314,7 +308,7 @@ public class QTI21ImportProcessor { ...@@ -314,7 +308,7 @@ public class QTI21ImportProcessor {
default: return qItemTypeDao.loadByType(QuestionType.UNKOWN.name()); default: return qItemTypeDao.loadByType(QuestionType.UNKOWN.name());
} }
} }
//additionalInformations, assessmentType
protected void processItemMetadata(QuestionItemImpl poolItem, AssessmentItemMetadata metadata) { protected void processItemMetadata(QuestionItemImpl poolItem, AssessmentItemMetadata metadata) {
//non heuristic set of question type //non heuristic set of question type
String typeStr = null; String typeStr = null;
...@@ -351,6 +345,7 @@ public class QTI21ImportProcessor { ...@@ -351,6 +345,7 @@ public class QTI21ImportProcessor {
poolItem.setTaxonomyLevel(taxonomyLevel); poolItem.setTaxonomyLevel(taxonomyLevel);
} }
//educational
String level = metadata.getLevel(); String level = metadata.getLevel();
if(StringHelper.containsNonWhitespace(level)) { if(StringHelper.containsNonWhitespace(level)) {
QTIMetadataConverter converter = new QTIMetadataConverter(qItemTypeDao, qLicenseDao, qEduContextDao, qpoolService); QTIMetadataConverter converter = new QTIMetadataConverter(qItemTypeDao, qLicenseDao, qEduContextDao, qpoolService);
...@@ -372,22 +367,26 @@ public class QTI21ImportProcessor { ...@@ -372,22 +367,26 @@ public class QTI21ImportProcessor {
if(StringHelper.containsNonWhitespace(editorVersion)) { if(StringHelper.containsNonWhitespace(editorVersion)) {
poolItem.setEditorVersion(editorVersion); poolItem.setEditorVersion(editorVersion);
} }
int numOfAnswerAlternatives = metadata.getNumOfAnswerAlternatives();
if(numOfAnswerAlternatives > 0) {
poolItem.setNumOfAnswerAlternatives(numOfAnswerAlternatives);
}
poolItem.setDifficulty(metadata.getDifficulty());
poolItem.setDifferentiation(metadata.getDifferentiation());
poolItem.setStdevDifficulty(metadata.getStdevDifficulty());
String license = metadata.getLicense(); String license = metadata.getLicense();
if(StringHelper.containsNonWhitespace(license)) { if(StringHelper.containsNonWhitespace(license)) {
QTIMetadataConverter converter = new QTIMetadataConverter(qItemTypeDao, qLicenseDao, qEduContextDao, qpoolService); QTIMetadataConverter converter = new QTIMetadataConverter(qItemTypeDao, qLicenseDao, qEduContextDao, qpoolService);
QLicense qLicense = converter.toLicense(license); QLicense qLicense = converter.toLicense(license);
poolItem.setLicense(qLicense); poolItem.setLicense(qLicense);
} }
//OpenOLAT
poolItem.setDifficulty(metadata.getDifficulty());
poolItem.setDifferentiation(metadata.getDifferentiation());
poolItem.setStdevDifficulty(metadata.getStdevDifficulty());
int numOfAnswerAlternatives = metadata.getNumOfAnswerAlternatives();
if(numOfAnswerAlternatives > 0) {
poolItem.setNumOfAnswerAlternatives(numOfAnswerAlternatives);
}
poolItem.setCreator(metadata.getCreator());
poolItem.setTopic(metadata.getTopic());
poolItem.setAssessmentType(metadata.getAssessmentType());
poolItem.setAdditionalInformations(metadata.getAdditionalInformations());
} }
public static class ImsManifestVisitor extends SimpleFileVisitor<Path> { public static class ImsManifestVisitor extends SimpleFileVisitor<Path> {
......
...@@ -28,9 +28,7 @@ import org.olat.core.gui.components.velocity.VelocityContainer; ...@@ -28,9 +28,7 @@ import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Event; import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.controller.BasicController;
import org.olat.ims.qti21.AssessmentSessionAuditLogger;
import org.olat.ims.qti21.QTI21Service; import org.olat.ims.qti21.QTI21Service;
import org.olat.ims.qti21.manager.audit.DefaultAssessmentSessionAuditLogger;
import org.olat.ims.qti21.ui.editor.AssessmentItemPreviewSolutionController; import org.olat.ims.qti21.ui.editor.AssessmentItemPreviewSolutionController;
import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.QPoolService;
import org.olat.modules.qpool.QuestionItem; import org.olat.modules.qpool.QuestionItem;
...@@ -48,7 +46,6 @@ public class QTI21PreviewController extends BasicController { ...@@ -48,7 +46,6 @@ public class QTI21PreviewController extends BasicController {
private final VelocityContainer mainVC; private final VelocityContainer mainVC;
private AssessmentItemPreviewSolutionController previewCtrl; private AssessmentItemPreviewSolutionController previewCtrl;
private AssessmentSessionAuditLogger candidateAuditLogger = new DefaultAssessmentSessionAuditLogger();
@Autowired @Autowired
private QTI21Service qtiService; private QTI21Service qtiService;
......
...@@ -54,7 +54,7 @@ public interface QuestionItemShort extends OLATResourceable, CreateInfo, Modifie ...@@ -54,7 +54,7 @@ public interface QuestionItemShort extends OLATResourceable, CreateInfo, Modifie
*/ */
public String getTaxonomyLevelName(); public String getTaxonomyLevelName();
public String getTaxonomicPath();; public String getTaxonomicPath();
public String getTopic(); public String getTopic();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment