/** * <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.qti.statistics; import org.dom4j.Document; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.stack.TooledStackedPanel; import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.gui.components.tree.GenericTreeNode; import org.olat.core.gui.components.tree.TreeModel; import org.olat.core.gui.components.tree.TreeNode; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.messages.MessageUIFactory; import org.olat.core.gui.translator.Translator; import org.olat.core.id.OLATResourceable; import org.olat.core.util.CodeHelper; import org.olat.core.util.Util; import org.olat.core.util.nodes.INode; import org.olat.core.util.resource.OresHelper; import org.olat.course.nodes.CourseNodeConfiguration; import org.olat.course.nodes.CourseNodeFactory; import org.olat.course.nodes.IQSELFCourseNode; import org.olat.course.nodes.IQSURVCourseNode; import org.olat.course.nodes.IQTESTCourseNode; import org.olat.course.nodes.QTICourseNode; import org.olat.course.nodes.TitledWrapperHelper; import org.olat.course.statistic.StatisticResourceNode; import org.olat.course.statistic.StatisticResourceResult; import org.olat.ims.qti.editor.beecom.objects.Item; import org.olat.ims.qti.editor.beecom.objects.QTIDocument; import org.olat.ims.qti.editor.beecom.objects.Section; import org.olat.ims.qti.editor.beecom.parser.ParserManager; import org.olat.ims.qti.editor.tree.ItemNode; import org.olat.ims.qti.editor.tree.SectionNode; import org.olat.ims.qti.process.ImsRepositoryResolver; import org.olat.ims.qti.statistics.model.StatisticAssessment; import org.olat.ims.qti.statistics.ui.QTI12AssessmentStatisticsController; import org.olat.ims.qti.statistics.ui.QTI12ItemStatisticsController; import org.olat.ims.qti.statistics.ui.QTI21OnyxAssessmentStatisticsController; import org.olat.repository.RepositoryEntry; import de.bps.onyx.plugin.OnyxModule; /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class QTIStatisticResourceResult implements StatisticResourceResult { private final QTICourseNode courseNode; private final OLATResourceable courseOres; private final QTIStatisticsManager qtiStatisticsManager; private StatisticAssessment statisticAssessment; private QTIDocument qtiDocument; private ImsRepositoryResolver resolver; private QTIStatisticSearchParams searchParams; private final RepositoryEntry qtiRepositoryEntry; private QTIType type; public QTIStatisticResourceResult(OLATResourceable courseOres, QTICourseNode courseNode, RepositoryEntry testEntry, QTIStatisticSearchParams searchParams) { this.courseNode = courseNode; this.searchParams = searchParams; this.courseOres = OresHelper.clone(courseOres); qtiStatisticsManager = CoreSpringFactory.getImpl(QTIStatisticsManager.class); qtiRepositoryEntry = testEntry; if(OnyxModule.isOnyxTest(qtiRepositoryEntry.getOlatResource())) { type = QTIType.onyx; } else { resolver = new ImsRepositoryResolver(qtiRepositoryEntry); Document doc = resolver.getQTIDocument(); if(doc != null) { ParserManager parser = new ParserManager(); qtiDocument = (QTIDocument) parser.parse(doc); if (courseNode instanceof IQSURVCourseNode) { type = QTIType.survey; } else if (courseNode instanceof IQTESTCourseNode) { type = QTIType.test; } else if (courseNode instanceof IQSELFCourseNode){ type = QTIType.self; } } } } public QTIType getType() { return type; } public OLATResourceable getCourseOres() { return courseOres; } public QTICourseNode getTestCourseNode() { return courseNode; } public RepositoryEntry getQTIRepositoryEntry() { return qtiRepositoryEntry; } public QTIDocument getQTIDocument() { return qtiDocument; } public String getMediaBaseURL() { return getResolver().getStaticsBaseURI() + "/"; } public QTIStatisticSearchParams getSearchParams() { return searchParams; } public StatisticAssessment getQTIStatisticAssessment() { if(statisticAssessment == null) { statisticAssessment = qtiStatisticsManager.getAssessmentStatistics(searchParams); } return statisticAssessment; } public ImsRepositoryResolver getResolver() { return resolver; } @Override public TreeModel getSubTreeModel() { GenericTreeModel subTreeModel; if(type == QTIType.onyx) { subTreeModel = new GenericTreeModel(); StatisticResourceNode rootTreeNode = new StatisticResourceNode(courseNode, this); subTreeModel.setRootNode(rootTreeNode); } else if(qtiDocument == null) { subTreeModel = null; } else { subTreeModel = new GenericTreeModel(); StatisticResourceNode rootTreeNode = new StatisticResourceNode(courseNode, this); subTreeModel.setRootNode(rootTreeNode); buildQTICourseNodeSubTree(qtiDocument, rootTreeNode); } return subTreeModel; } @Override public Controller getController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, TreeNode selectedNode) { return getController(ureq, wControl, stackPanel, selectedNode, false); } public Controller getController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, TreeNode selectedNode, boolean printMode) { if(selectedNode instanceof StatisticResourceNode) { return createAssessmentController(ureq, wControl, stackPanel, printMode); } else if(selectedNode instanceof SectionNode) { return createAssessmentController(ureq, wControl, stackPanel, printMode); } else if(selectedNode instanceof ItemNode) { Section section = null; INode sectionNode = selectedNode.getParent(); if(sectionNode instanceof SectionNode) { section = (Section) ((SectionNode)sectionNode).getUserObject(); } Item item = (Item)((ItemNode)selectedNode).getUserObject(); return createItemController(ureq, wControl, section, item, printMode); } return null; } private Controller createAssessmentController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, boolean printMode) { Controller ctrl; if (type == null) { Translator translator = Util.createPackageTranslator(QTI12AssessmentStatisticsController.class, ureq.getLocale()); String text = translator.translate("error.notfound.text"); ctrl = MessageUIFactory.createErrorMessage(ureq, wControl, null, text); } else if (type == QTIType.onyx){ ctrl = new QTI21OnyxAssessmentStatisticsController(ureq, wControl, this, printMode); } else { ctrl = new QTI12AssessmentStatisticsController(ureq, wControl, stackPanel, this, printMode); } CourseNodeConfiguration cnConfig = CourseNodeFactory.getInstance() .getCourseNodeConfigurationEvenForDisabledBB(courseNode.getType()); String iconCssClass = cnConfig.getIconCSSClass(); return TitledWrapperHelper.getWrapper(ureq, wControl, ctrl, courseNode, iconCssClass); } private Controller createItemController(UserRequest ureq, WindowControl wControl, Section section, Item item, boolean printMode) { return new QTI12ItemStatisticsController(ureq, wControl, section, item, this, printMode); } private void buildQTICourseNodeSubTree(QTIDocument qtiDoc, GenericTreeNode rootNode) { for(Section section:qtiDoc.getAssessment().getSections()) { GenericTreeNode sectionNode = new SectionNode(section, null); sectionNode.setUserObject(section); rootNode.addChild(sectionNode); for (Item item : section.getItems()) { GenericTreeNode itemNode = new ItemNode(item); itemNode.setIdent(Long.toString(CodeHelper.getForeverUniqueID())); if(sectionNode.getDelegate() == null) { sectionNode.setDelegate(itemNode); } itemNode.setUserObject(item); sectionNode.addChild(itemNode); } } } }