/**
* <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;
import java.io.File;
import java.net.URI;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.olat.basesecurity.IdentityRef;
import org.olat.core.gui.components.form.flexible.impl.MultipartFileInfos;
import org.olat.core.id.Identity;
import org.olat.ims.qti21.model.DigitalSignatureOptions;
import org.olat.ims.qti21.model.DigitalSignatureValidation;
import org.olat.ims.qti21.model.ParentPartItemRefs;
import org.olat.ims.qti21.model.ResponseLegality;
import org.olat.ims.qti21.model.audit.CandidateEvent;
import org.olat.ims.qti21.model.audit.CandidateItemEventType;
import org.olat.ims.qti21.model.audit.CandidateTestEventType;
import org.olat.modules.assessment.AssessmentEntry;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryRef;
import uk.ac.ed.ph.jqtiplus.JqtiExtensionManager;
import uk.ac.ed.ph.jqtiplus.node.AssessmentObject;
import uk.ac.ed.ph.jqtiplus.node.result.AssessmentResult;
import uk.ac.ed.ph.jqtiplus.notification.NotificationRecorder;
import uk.ac.ed.ph.jqtiplus.reading.QtiXmlReader;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentItem;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentObject;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentTest;
import uk.ac.ed.ph.jqtiplus.serialization.QtiSerializer;
import uk.ac.ed.ph.jqtiplus.state.ItemSessionState;
import uk.ac.ed.ph.jqtiplus.state.TestPlanNodeKey;
import uk.ac.ed.ph.jqtiplus.state.TestSessionState;
import uk.ac.ed.ph.jqtiplus.types.Identifier;
import uk.ac.ed.ph.jqtiplus.types.ResponseData.ResponseDataType;
import uk.ac.ed.ph.jqtiplus.xmlutils.xslt.XsltStylesheetCache;
import uk.ac.ed.ph.jqtiplus.xmlutils.xslt.XsltStylesheetManager;
/**
*
* Initial date: 12.05.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public interface QTI21Service {
public static final String PACKAGE_CONFIG_FILE_NAME = "QTI21PackageConfig.xml";
/**
* New QTI serializer
* @return
*/
public QtiSerializer qtiSerializer();
public QtiXmlReader qtiXmlReader();
/**
* The manager for custom extensions to QTI (MathExtensio )
* @return
*/
public JqtiExtensionManager jqtiExtensionManager();
/**
* @return The cache for stylesheets used by MathML transformation
*/
public XsltStylesheetCache getXsltStylesheetCache();
/**
* @return The stylesheets manager used by MathML transformation
*/
public XsltStylesheetManager getXsltStylesheetManager();
public URI createAssessmentTestUri(File resourceDirectory);
/**
* Load the assessmentTest based on the imsmanifest.xml found in the resource
* directory. Return null if the imsmanifest.xml is not found. The assessmentTest
* is cached.
*
* @param resourceDirectory The directory where is the package
* @param replace If true updates the cache
* @param debugInfo If true writes more infos
* @return The resolved assessment test or null if the imsmanifest.xml was not found.
*/
public ResolvedAssessmentTest loadAndResolveAssessmentTest(File resourceDirectory, boolean replace, boolean debugInfo);
/**
* The assessment item is load and cached.
*
* @param assessmentObjectSystemId
* @param resourceDirectory
* @return
*/
public ResolvedAssessmentItem loadAndResolveAssessmentItem(URI assessmentObjectSystemId, File resourceDirectory);
/**
* This method load a fresh instance from the disk and don't cache it. The instance can be changed and saved
* safely.
*
* @param assessmentObjectSystemId
* @param resourceDirectory
* @return
*/
public ResolvedAssessmentItem loadAndResolveAssessmentItemForCopy(URI assessmentObjectSystemId, File resourceDirectory);
public boolean updateAssesmentObject(File resourceFile, ResolvedAssessmentObject<?> resolvedAssessmentObject);
public boolean persistAssessmentObject(File resourceFile, AssessmentObject assessmentObject);
/**
*
* @param The test resource
* @return
*/
public boolean needManualCorrection(RepositoryEntry testEntry);
/**
*
* @param identities
* @param testEntry
* @param entry
* @param subIdent
* @return
*/
public boolean deleteAssessmentTestSession(List<Identity> identities, RepositoryEntryRef testEntry, RepositoryEntryRef entry, String subIdent);
/**
* Remove all test sessions in author mode, e.g. after an assessment test
* was changed.
*
* @param testEntry
* @return
*/
public boolean deleteAuthorAssessmentTestSession(RepositoryEntryRef testEntry);
/**
* Delete a specific test session.
*
* @param testSession
* @return
*/
public boolean deleteAssessmentTestSession(AssessmentTestSession testSession);
/**
* Set some extra options for the QTI package.
*
* @param testEntry
* @return
*/
public QTI21DeliveryOptions getDeliveryOptions(RepositoryEntry testEntry);
/**
* Set some extra options for the QTI 2.1 which are not part
* of the standard fomr IMS.
*
* @param testEntry
* @param options
*/
public void setDeliveryOptions(RepositoryEntry testEntry, QTI21DeliveryOptions options);
/**
* Check if some user made assessment with this test.
*
* @param testEntry
* @return
*/
public boolean isAssessmentTestActivelyUsed(RepositoryEntry testEntry);
public AssessmentTestSession createAssessmentTestSession(Identity identity, String anonymousIdentifier,
AssessmentEntry assessmentEntry, RepositoryEntry entry, String subIdent, RepositoryEntry testEntry,
boolean authorMode);
/**
* This create an transient session which are not saved on the database. But
* please, at the end of the session, delete the storage.
*
* @param identity
* @param anonymousIdentifier
* @param assessmentEntry
* @param entry
* @param subIdent
* @param testEntry
* @param authorMode
* @return
*/
public AssessmentTestSession createInMemoryAssessmentTestSession(Identity identity);
/**
* Return the implementation of the log audit.
*
* @param session
* @return
*/
public AssessmentSessionAuditLogger getAssessmentSessionAuditLogger(AssessmentTestSession session, boolean authorMode);
/**
* This will return the last session if it's not finished, terminated or exploded.
*
* @param identity The identity which play the session
* @param anonymousIdentifier The anonymous identifier which play the session
* @param entry The repository entry (course or test)
* @param subIdent The sub identifier (typically course element ident)
* @param testEntry The repository entry of the test
* @param authorMode If the sesssion is played as an author
* @return A test session
*/
public AssessmentTestSession getResumableAssessmentTestSession(Identity identity, String anonymousIdentifier,
RepositoryEntry entry, String subIdent, RepositoryEntry testEntry, boolean authorMode);
public AssessmentTestSession reloadAssessmentTestSession(AssessmentTestSession session);
public AssessmentTestSession updateAssessmentTestSession(AssessmentTestSession session);
public boolean isRunningAssessmentTestSession(RepositoryEntry entry, String subIdent, RepositoryEntry testEntry);
public List<AssessmentTestSession> getRunningAssessmentTestSession(RepositoryEntry entry, String subIdent, RepositoryEntry testEntry);
public TestSessionState loadTestSessionState(AssessmentTestSession session);
public AssessmentTestMarks createMarks(Identity identity, RepositoryEntry entry, String subIdent, RepositoryEntry testEntry, String marks);
public AssessmentTestMarks getMarks(Identity identity, RepositoryEntry entry, String subIdent, RepositoryEntry testEntry);
public AssessmentTestMarks updateMarks(AssessmentTestMarks marks);
public File getAssessmentResultFile(final AssessmentTestSession candidateSession);
/**
* Reload the test session by its key and fetch identity, user...
*
* @param assessmentTestSessionKey
* @return The assessment test session or null if not found.
*/
public AssessmentTestSession getAssessmentTestSession(Long assessmentTestSessionKey);
/**
* Retrieve the sessions of a user.
*
* @param courseEntry
* @param subIdent
* @param identity
* @return
*/
public List<AssessmentTestSession> getAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, IdentityRef identity);
/**
* Retrieve the last finished test session.
*
* @param courseEntry
* @param subIdent
* @param testEntry
* @param identity
* @return
*/
public AssessmentTestSession getLastAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, RepositoryEntry testEntry, IdentityRef identity);
/**
* Retrieve the sessions for a test.
*
* @param courseEntry
* @param subIdent
* @param testEntry
* @return
*/
public List<AssessmentTestSession> getAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, RepositoryEntry testEntry);
public AssessmentItemSession getOrCreateAssessmentItemSession(AssessmentTestSession candidateSession, ParentPartItemRefs parentParts, String assessmentItemIdentifier);
public List<AssessmentItemSession> getAssessmentItemSessions(AssessmentTestSession candidateSession);
public List<AssessmentItemSession> getAssessmentItemSessions(RepositoryEntryRef courseEntry, String subIdent, RepositoryEntry testEntry, String itemRef);
public AssessmentItemSession updateAssessmentItemSession(AssessmentItemSession itemSession);
public AssessmentResponse createAssessmentResponse(AssessmentTestSession candidateSession, AssessmentItemSession assessmentItemSession,
String responseIdentifier, ResponseLegality legality, ResponseDataType type);
public Map<Identifier, AssessmentResponse> getAssessmentResponses(AssessmentItemSession assessmentItemSession);
public void recordTestAssessmentResponses(AssessmentItemSession assessmentItemSession, Collection<AssessmentResponse> responses);
public AssessmentTestSession recordTestAssessmentResult(AssessmentTestSession candidateSession, TestSessionState testSessionState, AssessmentResult assessmentResult,
AssessmentSessionAuditLogger auditLogger);
/**
* Finish the test session. The assessment result is for the last time and would not updated anymore.
*
* @param candidateSession
* @param testSessionState
* @param assessmentResul
* @param timestamp
* @param digitalSignature
* @param bundle
* @return
*/
public AssessmentTestSession finishTestSession(AssessmentTestSession candidateSession, TestSessionState testSessionState, AssessmentResult assessmentResul,
Date timestamp, DigitalSignatureOptions signatureOptions, Identity assessedIdentity);
public void cancelTestSession(AssessmentTestSession candidateSession, TestSessionState testSessionState);
/**
* Sign the assessment result. Be careful, the file must not be changed
* after that!
*
* @param candidateSession
* @param sendMail
* @param mail
*/
public void signAssessmentResult(AssessmentTestSession candidateSession, DigitalSignatureOptions signatureOptions, Identity assessedIdentity);
public DigitalSignatureValidation validateAssessmentResult(File xmlSignature);
public CandidateEvent recordCandidateTestEvent(AssessmentTestSession candidateSession, RepositoryEntryRef testEntry, RepositoryEntryRef entry,
CandidateTestEventType textEventType, TestSessionState testSessionState, NotificationRecorder notificationRecorder);
public CandidateEvent recordCandidateTestEvent(AssessmentTestSession candidateSession, RepositoryEntryRef testEntry, RepositoryEntryRef entry,
CandidateTestEventType textEventType, CandidateItemEventType itemEventType,
TestPlanNodeKey itemKey, TestSessionState testSessionState, NotificationRecorder notificationRecorder);
/**
* Return the assessment result for the specified test session.
*
* @param candidateSession
* @return The assessment result
*/
public AssessmentResult getAssessmentResult(AssessmentTestSession candidateSession);
/**
* Return the file where the XML Digital Signature of the assessment result
* is saved or null if it not exists.
*
* @return The file
*/
public File getAssessmentResultSignature(AssessmentTestSession candidateSession);
/**
* Return the issue date saved in the XML Digital Signature
*
* @param candidateSession
* @return
*/
public Date getAssessmentResultSignatureIssueDate(AssessmentTestSession candidateSession);
public AssessmentTestSession finishItemSession(AssessmentTestSession candidateSession, AssessmentResult assessmentResul, Date timestamp);
public void recordItemAssessmentResult(AssessmentTestSession candidateSession, AssessmentResult assessmentResult, AssessmentSessionAuditLogger candidateAuditLogger);
public CandidateEvent recordCandidateItemEvent(AssessmentTestSession candidateSession, RepositoryEntryRef testEntry, RepositoryEntryRef entry,
CandidateItemEventType itemEventType, ItemSessionState itemSessionState, NotificationRecorder notificationRecorder);
public CandidateEvent recordCandidateItemEvent(AssessmentTestSession candidateSession, RepositoryEntryRef testEntry, RepositoryEntryRef entry,
CandidateItemEventType itemEventType, ItemSessionState itemSessionState);
/**
*
*/
public File getSubmissionDirectory(AssessmentTestSession candidateSession);
/**
* Import submitted file by an assessed identity in its session storage.
*
* @param candidateSession
* @param multipartFile
* @return
*/
public File importFileSubmission(AssessmentTestSession candidateSession, MultipartFileInfos multipartFile);
public File importFileSubmission(AssessmentTestSession candidateSession, String filename, byte[] data);
}