/**
* <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.components;
import static org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.valueContains;
import java.net.URI;
import java.util.Collections;
import org.apache.velocity.context.Context;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.AbstractComponent;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.control.JSAndCSSAdder;
import org.olat.core.gui.render.ValidationResult;
import org.olat.core.gui.render.velocity.VelocityComponent;
import org.olat.ims.qti21.ui.CandidateSessionContext;
import uk.ac.ed.ph.jqtiplus.node.content.variable.FeedbackElement;
import uk.ac.ed.ph.jqtiplus.node.item.ModalFeedback;
import uk.ac.ed.ph.jqtiplus.node.item.interaction.Interaction;
import uk.ac.ed.ph.jqtiplus.node.test.VisibilityMode;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentItem;
import uk.ac.ed.ph.jqtiplus.state.ItemSessionState;
import uk.ac.ed.ph.jqtiplus.types.Identifier;
import uk.ac.ed.ph.jqtiplus.value.Value;
import uk.ac.ed.ph.jqtiplus.xmlutils.locators.ResourceLocator;
/**
*
* Initial date: 04.06.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public abstract class AssessmentObjectComponent extends AbstractComponent implements VelocityComponent {
private Context context;
private String mapperUri;
private String submissionMapperUri;
private URI assessmentObjectUri;
private ResourceLocator resourceLocator;
private CandidateSessionContext candidateSessionContext;
public AssessmentObjectComponent(String name) {
super(name);
}
public abstract AssessmentObjectFormItem getQtiItem();
public String getMapperUri() {
return mapperUri;
}
public void setMapperUri(String mapperUri) {
this.mapperUri = mapperUri;
}
/**
* Allow to define a specific mapper uri for the uploaded files.
*
* @return The specific submission mapper uri or the standard one if it was not defined
*/
public String getSubmissionMapperUri() {
return submissionMapperUri == null ? mapperUri : submissionMapperUri;
}
public void setSubmissionMapperUri(String submissionMapperUri) {
this.submissionMapperUri = submissionMapperUri;
}
public URI getAssessmentObjectUri() {
return assessmentObjectUri;
}
public void setAssessmentObjectUri(URI assessmentObjectUri) {
this.assessmentObjectUri = assessmentObjectUri;
}
public abstract String getResponseUniqueIdentifier(ItemSessionState itemSessionState, Interaction interaction);
public abstract Interaction getInteractionOfResponseUniqueIdentifier(String responseUniqueId);
public abstract String relativePathTo(ResolvedAssessmentItem resolvedAssessmentItem);
public ResourceLocator getResourceLocator() {
return resourceLocator;
}
public void setResourceLocator(ResourceLocator resourceLocator) {
this.resourceLocator = resourceLocator;
}
public CandidateSessionContext getCandidateSessionContext() {
return candidateSessionContext;
}
public void setCandidateSessionContext(CandidateSessionContext candidateSessionContext) {
this.candidateSessionContext = candidateSessionContext;
}
//$itemSessionState/@entryTime!='' and not($isItemSessionEnded)
public boolean isItemSessionOpen(ItemSessionState itemSessionState, boolean solutionMode) {
return itemSessionState.getEntryTime() != null && !isItemSessionEnded(itemSessionState, solutionMode);
}
public boolean isItemSessionEnded(ItemSessionState itemSessionState, boolean solutionMode) {
return candidateSessionContext.isTerminated() || itemSessionState.getEndTime() != null || solutionMode;
}
//<xsl:variable name="identifierMatch" select="boolean(qw:value-contains(qw:get-outcome-value(@outcomeIdentifier), @identifier))" as="xs:boolean"/>
//<xsl:if test="($identifierMatch and @showHide='show') or (not($identifierMatch) and @showHide='hide')">
// <xsl:apply-templates/>
//</xsl:if>
public boolean isFeedback(FeedbackElement feedbackElement, ItemSessionState itemSessionState) {
Identifier outcomeIdentifier = feedbackElement.getOutcomeIdentifier();
Identifier identifier = feedbackElement.getIdentifier();
Value outcomeValue = itemSessionState.getOutcomeValues().get(outcomeIdentifier);
boolean identifierMatch = valueContains(outcomeValue, identifier);
return (identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.SHOW_IF_MATCH)
|| (!identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.HIDE_IF_MATCH);
}
public boolean isFeedback(ModalFeedback feedbackElement, ItemSessionState itemSessionState) {
Identifier outcomeIdentifier = feedbackElement.getOutcomeIdentifier();
Identifier identifier = feedbackElement.getIdentifier();
Value outcomeValue = itemSessionState.getOutcomeValues().get(outcomeIdentifier);
boolean identifierMatch = valueContains(outcomeValue, identifier);
return (identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.SHOW_IF_MATCH)
|| (!identifierMatch && feedbackElement.getVisibilityMode() == VisibilityMode.HIDE_IF_MATCH);
}
@Override
public Component getComponent(String name) {
return null;
}
@Override
public Iterable<Component> getComponents() {
return Collections.emptyList();
}
@Override
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
@Override
protected void doDispatchRequest(UserRequest ureq) {
//
}
@Override
public void validate(UserRequest ureq, ValidationResult vr) {
super.validate(ureq, vr);
JSAndCSSAdder jsa = vr.getJsAndCSSAdder();
jsa.addRequiredStaticJsFile("assessment/rendering/javascript/QtiWorksRendering.js");
jsa.addRequiredStaticJsFile("assessment/rendering/javascript/AsciiMathInputController.js");
jsa.addRequiredStaticJsFile("assessment/rendering/javascript/UpConversionAjaxController.js");
jsa.addRequiredStaticJsFile("js/jquery/maphilight/jquery.maphilight.js");
jsa.addRequiredStaticJsFile("js/jquery/ui/jquery-ui-1.11.4.custom.qti.min.js");
jsa.addRequiredStaticJsFile("js/jquery/openolat/jquery.paint.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.associate.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.graphicAssociate.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.graphicGap.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.graphicOrder.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.selectPoint.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.positionObject.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.slider.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.order.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.match.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.gapMatch.js");
jsa.addRequiredStaticJsFile("js/jquery/qti/jquery.hotspot.js");
}
@Override
public abstract AssessmentObjectComponentRenderer getHTMLRendererSingleton();
}