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

no-jira: QTI 2.1 with simple persistence, as xml file and in database

parent 576df156
No related branches found
No related tags found
No related merge requests found
Showing
with 709 additions and 95 deletions
/**
* <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;
/**
......
......@@ -19,6 +19,8 @@
*/
package org.olat.ims.qti21;
import java.util.Date;
import org.olat.core.id.CreateInfo;
import org.olat.core.id.ModifiedInfo;
......@@ -29,5 +31,19 @@ import org.olat.core.id.ModifiedInfo;
*
*/
public interface UserTestSession extends CreateInfo, ModifiedInfo {
public Long getKey();
public Date getFinishTime();
public void setFinishTime(Date timestamp);
public Date getTerminationTime();
public void setTerminationTime(Date timestamp);
public boolean isExploded();
}
/**
* <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.manager;
import java.io.File;
import java.io.OutputStream;
import java.net.URI;
import java.util.Date;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.util.FileUtils;
import org.olat.core.util.WebappHelper;
import org.olat.ims.qti21.UserTestSession;
import org.olat.ims.qti21.model.CandidateEvent;
import org.olat.ims.qti21.model.CandidateItemEventType;
import org.olat.ims.qti21.model.CandidateTestEventType;
import org.springframework.stereotype.Service;
import uk.ac.ed.ph.jqtiplus.JqtiExtensionManager;
import uk.ac.ed.ph.jqtiplus.node.QtiNode;
import uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult;
import uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder;
import uk.ac.ed.ph.jqtiplus.running.TestSessionController;
import uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer;
import uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey;
import uk.ac.ed.ph.jqtiplus.state.TestSessionState;
@Service
public class CandidateDataService {
//@Resource
private QtiSerializer qtiSerializer = new QtiSerializer(new JqtiExtensionManager());
public AssessmentResult computeAndRecordTestAssessmentResult(UserTestSession candidateSession, TestSessionController testSessionController) {
AssessmentResult assessmentResult = computeTestAssessmentResult(candidateSession, testSessionController);
recordTestAssessmentResult(candidateSession, assessmentResult);
return assessmentResult;
}
public AssessmentResult computeTestAssessmentResult(final UserTestSession candidateSession, final TestSessionController testSessionController) {
String baseUrl = "http://localhost:8080/olat";
final URI sessionIdentifierSourceId = URI.create(baseUrl);
final String sessionIdentifier = "testsession/" + candidateSession.getKey();
Date timestamp = new Date();//requestTimestampContext.getCurrentRequestTimestamp();
return testSessionController.computeAssessmentResult(timestamp, sessionIdentifier, sessionIdentifierSourceId);
}
public void recordTestAssessmentResult(final UserTestSession candidateSession, final AssessmentResult assessmentResult) {
/* First record full result XML to filesystem */
storeAssessmentResultFile(candidateSession, assessmentResult);
/* Then record test outcome variables to DB */
//recordOutcomeVariables(candidateSession, assessmentResult.getTestResult());
}
private void storeAssessmentResultFile(final UserTestSession candidateSession, final QtiNode resultNode) {
final File resultFile = getAssessmentResultFile(candidateSession);
try(OutputStream resultStream = FileUtils.getBos(resultFile);) {
qtiSerializer.serializeJqtiObject(resultNode, resultStream);
} catch (final Exception e) {
throw new OLATRuntimeException("Unexpected", e);
}
}
private File getAssessmentResultFile(final UserTestSession candidateSession) {
File sessionFolder = new File(getFullQtiPath(), candidateSession.getKey().toString());
if(!sessionFolder.exists()) {
sessionFolder.mkdirs();
}
return new File(sessionFolder, "assessmentResult.xml");
}
private File getFullQtiPath() {
return new File(WebappHelper.getUserDataRoot(), "qti21");
}
public CandidateEvent recordCandidateTestEvent(UserTestSession candidateSession, CandidateTestEventType textEventType,
TestSessionState testSessionState, NotificationRecorder notificationRecorder) {
return recordCandidateTestEvent(candidateSession, textEventType, null, null, testSessionState, notificationRecorder);
}
public CandidateEvent recordCandidateTestEvent(UserTestSession candidateSession, CandidateTestEventType textEventType,
CandidateItemEventType itemEventType, TestSessionState testSessionState, NotificationRecorder notificationRecorder) {
CandidateEvent event = new CandidateEvent();
event.setTestEventType(textEventType);
return recordCandidateTestEvent(candidateSession, textEventType, itemEventType, null, testSessionState, notificationRecorder);
}
public CandidateEvent recordCandidateTestEvent(UserTestSession candidateSession, CandidateTestEventType textEventType,
CandidateItemEventType itemEventType, TestPlanNodeKey itemKey, TestSessionState testSessionState, NotificationRecorder notificationRecorder) {
CandidateEvent event = new CandidateEvent();
event.setTestEventType(textEventType);
event.setItemEventType(itemEventType);
if (itemKey!=null) {
event.setTestItemKey(itemKey.toString());
}
return event;
}
}
/**
* <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.manager;
import org.olat.core.commons.persistence.DB;
......
/**
* <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.manager;
import java.util.Date;
......@@ -36,5 +55,9 @@ public class TestSessionDAO {
dbInstance.getCurrentEntityManager().persist(testSession);
return testSession;
}
public UserTestSession update(UserTestSession testSession) {
return dbInstance.getCurrentEntityManager().merge(testSession);
}
}
/**
* <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;
/**
*
* Initial date: 19.05.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class CandidateEvent {
private CandidateTestEventType testEventType;
private CandidateItemEventType itemEventType;
private String testItemKey;
public CandidateTestEventType getTestEventType() {
return testEventType;
}
public void setTestEventType(CandidateTestEventType testEventType) {
this.testEventType = testEventType;
}
public CandidateItemEventType getItemEventType() {
return itemEventType;
}
public void setItemEventType(CandidateItemEventType itemEventType) {
this.itemEventType = itemEventType;
}
public String getTestItemKey() {
return testItemKey;
}
public void setTestItemKey(String testItemKey) {
this.testItemKey = testItemKey;
}
}
/* Copyright (c) 2012-2013, University of Edinburgh.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* * Neither the name of the University of Edinburgh nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* This software is derived from (and contains code from) QTItools and MathAssessEngine.
* QTItools is (c) 2008, University of Southampton.
* MathAssessEngine is (c) 2010, University of Edinburgh.
*/
package org.olat.ims.qti21.model;
/**
* Enumerates the item-specific events that can happen when delivering
* an item or test within a {@link CandidateSession}
*
* @author David McKain
*/
public enum CandidateItemEventType {
/* NB: Observe maximum length for mapped column set in CandidateEvent */
//1234567890123456789012345678901234567890
/**
* Item session first initialised and template processing happened
* (NB: Only in standalone item sessions)
*/
ENTER,
/** Responses made and counted as attempt, all responses bound successfully and valid */
ATTEMPT_VALID,
/** Responses saved but not yet counted as attempt, all responses bound successfully and valid */
RESPONSE_VALID,
/** Responses made, all responses bound successfully but some invalid */
RESPONSE_INVALID,
/** Attempt made, some responses bound unsuccessfully */
RESPONSE_BAD,
/** Candidate has re-initialised the session (i.e. template processing has been redone) */
REINIT,
/**
* Candidate has reset the session back to the state immediately after the last
* reinit (or after the {@link #ENTER} if there were no reinits)
*/
RESET,
/**
* Candidate has requested a model solution to be rendered.
* (This closes the session if it hasn't already been closed)
*/
SOLUTION,
/**
* Candidate has ended (closed) the current session
*/
END,
/**
* Candidate has exited (terminated) the session
*/
EXIT,
;
}
/**
* <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;
import java.util.Date;
......
/**
* <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.ui;
import org.olat.ims.qti21.UserTestSession;
import org.olat.ims.qti21.model.CandidateEvent;
public interface CandidateSessionContext {
public boolean isTerminated();
public UserTestSession getCandidateSession();
public CandidateEvent getLastEvent();
}
......@@ -43,6 +43,7 @@ public class QTI21Component extends AbstractComponent {
private URI assessmentObjectUri;
private ResourceLocator resourceLocator;
private TestSessionController testSessionController;
private CandidateSessionContext candidateSessionContext;
private RequestTimestampContext requestTimestampContext;
private final QTI21FormItem qtiItem;
......@@ -72,6 +73,14 @@ public class QTI21Component extends AbstractComponent {
this.testSessionController = testSessionController;
}
public CandidateSessionContext getCandidateSessionContext() {
return candidateSessionContext;
}
public void setCandidateSessionContext(CandidateSessionContext candidateSessionContext) {
this.candidateSessionContext = candidateSessionContext;
}
public RequestTimestampContext getRequestTimestampContext() {
return requestTimestampContext;
}
......
......@@ -34,15 +34,22 @@ import org.olat.core.gui.render.Renderer;
import org.olat.core.gui.render.StringOutput;
import org.olat.core.gui.render.URLBuilder;
import org.olat.core.gui.translator.Translator;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.ims.qti21.RequestTimestampContext;
import org.olat.ims.qti21.UserTestSession;
import org.olat.ims.qti21.model.CandidateEvent;
import org.olat.ims.qti21.model.CandidateTestEventType;
import org.olat.ims.qti21.ui.rendering.AbstractRenderingOptions;
import org.olat.ims.qti21.ui.rendering.AbstractRenderingRequest;
import org.olat.ims.qti21.ui.rendering.AssessmentRenderer;
import org.olat.ims.qti21.ui.rendering.SerializationMethod;
import org.olat.ims.qti21.ui.rendering.TerminatedRenderingRequest;
import org.olat.ims.qti21.ui.rendering.TestRenderingMode;
import org.olat.ims.qti21.ui.rendering.TestRenderingOptions;
import org.olat.ims.qti21.ui.rendering.TestRenderingRequest;
import uk.ac.ed.ph.jqtiplus.running.TestSessionController;
import uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey;
import uk.ac.ed.ph.jqtiplus.state.TestSessionState;
/**
......@@ -127,14 +134,15 @@ public class QTI21ComponentRenderer extends DefaultComponentRenderer {
private void renderCurrentCandidateTestSessionState(TestSessionController testSessionController,
TestRenderingOptions renderingOptions, StreamResult result, QTI21Component component) {
TestSessionState testSessionState = testSessionController.getTestSessionState();
/*final CandidateSession candidateSession = candidateSessionContext.getCandidateSession();
CandidateSessionContext candidateSessionContext = component.getCandidateSessionContext();
final UserTestSession candidateSession = candidateSessionContext.getCandidateSession();
if (candidateSession.isExploded()) {
renderExploded(candidateSessionContext, renderingOptions, result);
}*/
/*
renderExploded(candidateSessionContext, renderingOptions, result, component);
}
if (candidateSessionContext.isTerminated()) {
renderTerminated(result);
} else {*/
renderTerminated(candidateSessionContext, renderingOptions, result, component);
} else {
/* Look up most recent event */
// final CandidateEvent latestEvent = assertSessionEntered(candidateSession);
......@@ -151,13 +159,36 @@ public class QTI21ComponentRenderer extends DefaultComponentRenderer {
/* Render event */
renderTestEvent(testSessionController, renderingOptions, result, component);
//}
}
}
private void renderExploded(CandidateSessionContext candidateSessionContext, AbstractRenderingOptions renderingOptions, StreamResult result, QTI21Component component) {
assessmentRenderer.renderExploded(createTerminatedRenderingRequest(candidateSessionContext, renderingOptions, component), result);
}
private void renderTerminated(CandidateSessionContext candidateSessionContext, AbstractRenderingOptions renderingOptions, StreamResult result, QTI21Component component) {
assessmentRenderer.renderTeminated(createTerminatedRenderingRequest(candidateSessionContext, renderingOptions, component), result);
}
//----------------------------------------------------
private TerminatedRenderingRequest createTerminatedRenderingRequest(CandidateSessionContext candidateSessionContext,
AbstractRenderingOptions renderingOptions, QTI21Component component) {
final TerminatedRenderingRequest renderingRequest = new TerminatedRenderingRequest();
initRenderingRequest(renderingRequest, renderingOptions, component);
//renderingRequest.setExitSessionUrl(candidateSessionContext.getReturnUrl());
return renderingRequest;
}
private void renderTestEvent(final TestSessionController testSessionController,
final TestRenderingOptions renderingOptions, final StreamResult result, QTI21Component component) {
//final CandidateTestEventType testEventType = candidateEvent.getTestEventType();
//final CandidateSession candidateSession = candidateEvent.getCandidateSession();
CandidateSessionContext candidateSessionContext = component.getCandidateSessionContext();
//final CandidateTestEventType testEventType = candidateEvent.getTestEventType();
CandidateEvent candidateEvent = candidateSessionContext.getLastEvent();
CandidateTestEventType testEventType = candidateEvent.getTestEventType();
final UserTestSession candidateSession = candidateSessionContext.getCandidateSession();//candidateEvent.getCandidateSession();
/* Create and partially configure rendering request */
final TestRenderingRequest renderingRequest = new TestRenderingRequest();
......@@ -166,7 +197,7 @@ public class QTI21ComponentRenderer extends DefaultComponentRenderer {
/* If session has terminated, render appropriate state and exit */
final TestSessionState testSessionState = testSessionController.getTestSessionState();
if (/* candidateSession.isTerminated() ||*/ testSessionState.isExited()) {
if (candidateSessionContext.isTerminated() || testSessionState.isExited()) {
//assessmentRenderer.renderTeminated(createTerminatedRenderingRequest(candidateSessionContext, renderingRequest.getRenderingOptions()), result);
return;
}
......@@ -174,21 +205,29 @@ public class QTI21ComponentRenderer extends DefaultComponentRenderer {
/* Check for "modal" events first. These cause a particular rendering state to be
* displayed, which candidate will then leave.
*/
/*if (testEventType==CandidateTestEventType.REVIEW_ITEM) {
if (testEventType == CandidateTestEventType.REVIEW_ITEM) {
// Extract item to review
renderingRequest.setTestRenderingMode(TestRenderingMode.ITEM_REVIEW);
renderingRequest.setModalItemKey(extractTargetItemKey(candidateEvent));
}
else if (testEventType==CandidateTestEventType.SOLUTION_ITEM) {
} else if (testEventType == CandidateTestEventType.SOLUTION_ITEM) {
// Extract item to show solution
renderingRequest.setTestRenderingMode(TestRenderingMode.ITEM_SOLUTION);
renderingRequest.setModalItemKey(extractTargetItemKey(candidateEvent));
}*/
}
/* Pass to rendering layer */
assessmentRenderer.renderTest(renderingRequest, result);
}
private TestPlanNodeKey extractTargetItemKey(final CandidateEvent candidateEvent) {
final String keyString = candidateEvent.getTestItemKey();
try {
return TestPlanNodeKey.fromString(keyString);
} catch (final Exception e) {
throw new OLATRuntimeException("Unexpected Exception parsing TestPlanNodeKey " + keyString, e);
}
}
private <P extends AbstractRenderingOptions> void initRenderingRequest(
final AbstractRenderingRequest<P> renderingRequest, final P renderingOptions, QTI21Component component) {
......
......@@ -19,8 +19,6 @@
*/
package org.olat.ims.qti21.ui;
import static org.olat.ims.qti21.ui.QTIWorksEvent.Event.response;
import static org.olat.ims.qti21.ui.QTIWorksEvent.Event.selectItem;
import static org.olat.ims.qti21.ui.QTIWorksEvent.Event.*;
import java.net.URI;
......@@ -80,6 +78,14 @@ public class QTI21FormItem extends FormItemImpl {
component.setTestSessionController(testSessionController);
}
public CandidateSessionContext getCandidateSessionContext() {
return component.getCandidateSessionContext();
}
public void setCandidateSessionContext(CandidateSessionContext candidateSessionContext) {
component.setCandidateSessionContext(candidateSessionContext);
}
public RequestTimestampContext getRequestTimestampContext() {
return component.getRequestTimestampContext();
}
......
/**
* <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.ui;
import java.util.Map;
......
/**
* <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.ui;
import java.io.File;
......@@ -41,6 +60,4 @@ public class ResourcesMapper implements Mapper {
}
return resource;
}
}
}
\ No newline at end of file
......@@ -106,6 +106,7 @@ public class AssessmentRenderer {
private static final URI testPartFeedbackXsltUri = URI.create("classpath:/rendering-xslt/test-testpart-feedback.xsl");
private static final URI testFeedbackXsltUri = URI.create("classpath:/rendering-xslt/test-feedback.xsl");
private static final URI terminatedXsltUri = URI.create("classpath:/rendering-xslt/terminated.xsl");
private static final URI explodedXsltUri = URI.create("classpath:/rendering-xslt/exploded.xsl");
......@@ -343,6 +344,23 @@ public class AssessmentRenderer {
/* We finally do the transform on the _item_ (NB!) */
doTransform(request, itemSystemId, testItemXsltUri, xsltParameters, result);
}
/**
* Renders an exploded session, sending the result to the provided JAXP {@link Result}.
* <p>
* NB: If you're using a {@link StreamResult} then you probably want to wrap it around an
* {@link OutputStream} rather than a {@link Writer}. Remember that you are responsible for
* closing the {@link OutputStream} or {@link Writer} afterwards!
*/
public void renderExploded(final TerminatedRenderingRequest request, final Result result) {
Assert.notNull(result, "result");
final Map<String, Object> xsltParameters = new HashMap<String, Object>();
setBaseRenderingParameters(xsltParameters, request, null);
xsltParameters.put("exitSessionUrl", request.getExitSessionUrl());
doTransform(request, null, explodedXsltUri, xsltParameters, result);
}
/**
* Renders a terminated session, sending the result to the provided JAXP {@link Result}.
......
......@@ -283,7 +283,7 @@ NB: This is used both while being presented, and during review.
<xsl:if test="$isItemSessionOpen">
<div class="testItemControl">
<input id="submit_button" name="submit" type="submit" value="{$submitButtonText}"/>
<input id="submit_button" name="submit" type="submit" value="{$submitButtonText}" class="btn btn-default"/>
</div>
</xsl:if>
</form>
......
/**
* <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.manager;
import org.junit.Assert;
......
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