/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.ims.qti21.model.xml; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import java.util.UUID; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.ims.qti21.model.IdentifierGenerator; import org.olat.imscp.xml.manifest.FileType; import org.olat.imscp.xml.manifest.ManifestMetadataType; import org.olat.imscp.xml.manifest.ManifestType; import org.olat.imscp.xml.manifest.MetadataType; import org.olat.imscp.xml.manifest.ResourceType; import org.olat.imscp.xml.manifest.ResourcesType; import org.olat.imsmd.xml.manifest.LomType; import org.olat.imsmd.xml.manifest.TechnicalType; /** * manifest * -> metadata * -> organizations * -> resources * -> -> resource * -> -> -> metadata * -> -> -> file * -> -> -> dependency * Initial date: 22.02.2016<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class ManifestBuilder { private static final OLog log = Tracing.createLoggerFor(ManifestBuilder.class); protected static final org.olat.oo.xml.manifest.ObjectFactory ooObjectFactory = new org.olat.oo.xml.manifest.ObjectFactory(); protected static final org.olat.imscp.xml.manifest.ObjectFactory cpObjectFactory = new org.olat.imscp.xml.manifest.ObjectFactory(); protected static final org.olat.imsmd.xml.manifest.ObjectFactory mdObjectFactory = new org.olat.imsmd.xml.manifest.ObjectFactory(); protected static final org.olat.imsqti.xml.manifest.ObjectFactory qtiObjectFactory = new org.olat.imsqti.xml.manifest.ObjectFactory(); public static final String ASSESSMENTTEST_MIMETYPE = "text/x-imsqti-test-xml"; public static final String ASSESSMENTITEM_MIMETYPE = "text/x-imsqti-item-xml"; public static final String SCHEMA_LOCATIONS = "http://www.imsglobal.org/xsd/imscp_v1p1 http://www.imsglobal.org/xsd/imscp_v1p2.xsd http://www.imsglobal.org/xsd/imsmd_v1p2 http://www.imsglobal.org/xsd/imsmd_v1p2p4.xsd http://www.imsglobal.org/xsd/imsqti_metadata_v2p1 http://www.imsglobal.org/xsd/qti/qtiv2p1/imsqti_metadata_v2p1.xsd"; private static JAXBContext context; static { try { context = JAXBContext.newInstance("org.olat.imscp.xml.manifest:org.olat.imsqti.xml.manifest:org.olat.imsmd.xml.manifest:org.olat.oo.xml.manifest"); } catch (JAXBException e) { log.error("", e); } } private final ManifestType manifest; public ManifestBuilder() { manifest = cpObjectFactory.createManifestType(); } public ManifestBuilder(ManifestType manifest) { this.manifest = manifest; } /** * Create a manifest with some metadata specific to the * assessment test. * * @return */ public static ManifestBuilder createAssessmentTestBuilder() { ManifestBuilder builder = new ManifestBuilder(); //schema ManifestMetadataType metadataType = createManifestMetadataType(); metadataType.setSchema("QTIv2.1 Package"); metadataType.setSchemaversion("1.0.0"); builder.manifest.setMetadata(metadataType); //lom technical LomType lom = createLom(true, true); metadataType.getAny().add(mdObjectFactory.createLom(lom)); return builder; } /** * Create a manifest with some metadata specific to the * assessment item. * * @return */ public static ManifestBuilder createAssessmentItemBuilder() { ManifestBuilder builder = new ManifestBuilder(); //schema ManifestMetadataType metadataType = createManifestMetadataType(); builder.manifest.setMetadata(metadataType); //lom technical LomType lom = createLom(false, true); metadataType.getAny().add(mdObjectFactory.createLom(lom)); return builder; } private static ManifestMetadataType createManifestMetadataType() { ManifestMetadataType metadataType = cpObjectFactory.createManifestMetadataType(); metadataType.setSchema("QTIv2.1 Package"); metadataType.setSchemaversion("1.0.0"); return metadataType; } private static LomType createLom(boolean assessmentTest, boolean assessmentItem) { LomType lom = mdObjectFactory.createLomType(); TechnicalType technical = mdObjectFactory.createTechnicalType(); if(assessmentTest) { technical.getContent().add(createTechnicalFormat(ASSESSMENTTEST_MIMETYPE)); } if(assessmentItem) { technical.getContent().add(createTechnicalFormat(ASSESSMENTITEM_MIMETYPE)); } return lom; } private static JAXBElement<String> createTechnicalFormat(String format) { return mdObjectFactory.createFormat(format); } public String appendAssessmentTest() { String testId = "test" + UUID.randomUUID().toString(); String testFilename = testId + ".xml"; appendAssessmentTest(testId, testFilename); return testFilename; } public String appendAssessmentTest(String testFilename) { String testId = "test" + UUID.randomUUID().toString(); appendAssessmentTest(testId, testFilename); return testFilename; } private final void appendAssessmentTest(String testId, String testFilename) { ResourceType testResourceType = cpObjectFactory.createResourceType(); testResourceType.setIdentifier(testId); testResourceType.setType("imsqti_test_xmlv2p1"); testResourceType.setHref(testFilename); getResourceList().add(testResourceType); appendFile(testResourceType, testFilename); } public String appendAssessmentItem() { String itemId = IdentifierGenerator.newAsString("item"); String itemFileName = itemId + ".xml"; appendAssessmentItem(itemId, itemFileName); return itemFileName; } public ResourceType appendAssessmentItem(String itemFileName) { String itemId = IdentifierGenerator.newAsString("item"); return appendAssessmentItem(itemId, itemFileName); } public ManifestMetadataBuilder getResourceBuilderByIdentifier(String resourceId) { ResourceType resourceType = getResourceTypeByIdentifier(resourceId); MetadataType metadata = getMetadata(resourceType); return metadata == null ? null : new ManifestMetadataBuilder(metadata); } public ResourceType getResourceTypeByIdentifier(String resourceId) { List<ResourceType> resources = getResourceList(); for(ResourceType resource:resources) { if(resourceId.equals(resource.getIdentifier())) { return resource; } } return null; } public ManifestMetadataBuilder getResourceBuilderByHref(String href) { ResourceType resourceType = getResourceTypeByHref(href); MetadataType metadata = getMetadata(resourceType); return metadata == null ? null : new ManifestMetadataBuilder(metadata); } public MetadataType getMetadata(ResourceType resourceType) { if(resourceType == null) return null; MetadataType metadata = resourceType.getMetadata(); if(metadata == null) { metadata = cpObjectFactory.createMetadataType(); resourceType.setMetadata(metadata); } return metadata; } public ResourceType getResourceTypeByHref(String href) { List<ResourceType> resources = getResourceList(); for(ResourceType resource:resources) { if(href.equals(resource.getHref())) { return resource; } } return null; } public ResourceType appendAssessmentItem(String itemId, String itemFileName) { ResourceType itemResourceType = cpObjectFactory.createResourceType(); itemResourceType.setIdentifier(itemId); itemResourceType.setType("imsqti_item_xmlv2p1"); itemResourceType.setHref(itemFileName); getResourceList().add(itemResourceType); appendFile(itemResourceType, itemFileName); return itemResourceType; } public List<ResourceType> getResourceList() { ResourcesType resources = manifest.getResources(); if(resources == null) { resources = cpObjectFactory.createResourcesType(); manifest.setResources(resources); } return resources.getResource(); } public void appendFile(ResourceType resource, String href) { FileType itemFileType = cpObjectFactory.createFileType(); itemFileType.setHref(href); resource.getFile().add(itemFileType); } public ManifestMetadataBuilder getMetadataBuilder(ResourceType resource, boolean create) { MetadataType metadata = getMetadataType(resource, create); return metadata == null ? null : new ManifestMetadataBuilder(metadata); } public MetadataType getMetadataType(ResourceType resource, boolean create) { if(resource == null) return null; MetadataType metadata = resource.getMetadata(); if(metadata == null && create) { metadata = cpObjectFactory.createMetadataType(); resource.setMetadata(metadata); } return metadata; } public void remove(ResourceType resource) { manifest.getResources().getResource().remove(resource); } public void build() { // } public final void write(File file) { build(); try(OutputStream out = new FileOutputStream(file)) { Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, SCHEMA_LOCATIONS); marshaller.marshal(cpObjectFactory.createManifest(manifest), out); } catch (JAXBException | IOException e) { log.error("", e); } } public final void write(OutputStream out) { build(); try { Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, SCHEMA_LOCATIONS); marshaller.marshal(cpObjectFactory.createManifest(manifest), out); } catch (JAXBException e) { log.error("", e); e.printStackTrace(); } } public static final ManifestBuilder read(File file) { try(InputStream in = new FileInputStream(file )) { ManifestType manifest = (ManifestType)((JAXBElement<?>)context .createUnmarshaller().unmarshal(in)).getValue(); return new ManifestBuilder(manifest); } catch (JAXBException | IOException e) { log.error("", e); return null; } } public static final ManifestBuilder read(InputStream in) { try { ManifestType manifest = (ManifestType)((JAXBElement<?>)context .createUnmarshaller().unmarshal(in)).getValue(); return new ManifestBuilder(manifest); } catch (JAXBException e) { log.error("", e); return null; } } }