/**
* <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 java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.olat.basesecurity.Group;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.course.nodes.CourseNode;
import org.olat.ims.qti.QTIResult;
import org.olat.ims.qti.QTIResultManager;
import org.olat.ims.qti.editor.beecom.parser.ItemParser;
import org.olat.ims.qti.export.QTIArchiver;
import org.olat.ims.qti.export.QTIExportEssayItemFormatConfig;
import org.olat.ims.qti.export.QTIExportFIBItemFormatConfig;
import org.olat.ims.qti.export.QTIExportFormatter;
import org.olat.ims.qti.export.QTIExportFormatterCSVType1;
import org.olat.ims.qti.export.QTIExportFormatterCSVType3;
import org.olat.ims.qti.export.QTIExportItemFormatConfig;
import org.olat.ims.qti.export.QTIExportKPRIMItemFormatConfig;
import org.olat.ims.qti.export.QTIExportMCQItemFormatConfig;
import org.olat.ims.qti.export.QTIExportManager;
import org.olat.ims.qti.export.QTIExportSCQItemFormatConfig;
import org.olat.ims.qti.export.helper.QTIItemObject;
import org.olat.ims.qti.export.helper.QTIObjectTreeBuilder;
/**
*
* Initial date: 17.03.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class QTIStatisticsResource implements MediaResource {
private static final OLog log = Tracing.createLoggerFor(QTIStatisticsResource.class);
private final Locale locale;
private final String encoding = "UTF-8";
private final QTIStatisticResourceResult resourceResult;
public QTIStatisticsResource(QTIStatisticResourceResult resourceResult, Locale locale) {
this.resourceResult = resourceResult;
this.locale = locale;
}
@Override
public boolean acceptRanges() {
return false;
}
@Override
public String getContentType() {
return "application/zip";
}
@Override
public Long getSize() {
return null;
}
@Override
public InputStream getInputStream() {
return null;
}
@Override
public Long getLastModified() {
return null;
}
@Override
public void prepare(HttpServletResponse hres) {
try {
hres.setCharacterEncoding(encoding);
} catch (Exception e) {
log.error("", e);
}
CourseNode courseNode = resourceResult.getTestCourseNode();
String label = courseNode.getType() + "_"
+ StringHelper.transformDisplayNameToFileSystemName(courseNode.getShortName())
+ "_" + Formatter.formatDatetimeFilesystemSave(new Date(System.currentTimeMillis()))
+ ".csv";
String urlEncodedLabel = StringHelper.urlEncodeUTF8(label);
hres.setHeader("Content-Disposition","attachment; filename*=UTF-8''" + urlEncodedLabel);
hres.setHeader("Content-Description", urlEncodedLabel);
try {
String sep = "\\t"; // fields separated by
String emb = "\""; // fields embedded by
String car = "\\r\\n"; // carriage return
sep = QTIArchiver.convert2CtrlChars(sep);
car = QTIArchiver.convert2CtrlChars(car);
int exportType = 1;
QTIExportFormatter formatter;
if (QTIType.test.equals(resourceResult.getType())){
exportType = 1;
formatter = new QTIExportFormatterCSVType1(locale, sep, emb, car, true);
} else if (QTIType.survey.equals(resourceResult.getType())) {
exportType = 2;
formatter = new QTIExportFormatterCSVType3(locale, null, sep, emb, car, true);
} else {
return;
}
Long qtiRepoEntryKey = resourceResult.getQTIRepositoryEntry().getKey();
List<QTIItemObject> itemList = new QTIObjectTreeBuilder().getQTIItemObjectList(resourceResult.getResolver());
formatter.setMapWithExportItemConfigs(getQTIItemConfigs(itemList));
QTIResultManager qrm = QTIResultManager.getInstance();
QTIStatisticSearchParams params = resourceResult.getSearchParams();
List<Group> limitToGroups = params.isMayViewAllUsersAssessments()
? null : params.getLimitToGroups();
List<QTIResult> results = qrm.selectResults(resourceResult.getCourseOres().getResourceableId(),
courseNode.getIdent(), qtiRepoEntryKey, limitToGroups, exportType);
QTIExportManager.getInstance().exportResults(formatter, results, itemList, hres.getOutputStream());
} catch (Exception e) {
log.error("", e);
}
}
@Override
public void release() {
//
}
/**
* Copy of QTIArchiveWizardController.getQTIItemConfigs but with all options set
* to true except for the time column.
*
* @param itemList
* @return
*/
private final static Map<Class<?>, QTIExportItemFormatConfig> getQTIItemConfigs(List<QTIItemObject> itemList){
Map<Class<?>, QTIExportItemFormatConfig> itConfigs = new HashMap<>();
for (Iterator<QTIItemObject> iter = itemList.iterator(); iter.hasNext();) {
QTIItemObject item = iter.next();
if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_SCQ)){
if (itConfigs.get(QTIExportSCQItemFormatConfig.class) == null){
QTIExportSCQItemFormatConfig confSCQ = new QTIExportSCQItemFormatConfig(true, true, true, false);
itConfigs.put(QTIExportSCQItemFormatConfig.class, confSCQ);
}
} else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_MCQ)){
if (itConfigs.get(QTIExportMCQItemFormatConfig.class) == null){
QTIExportMCQItemFormatConfig confMCQ = new QTIExportMCQItemFormatConfig(true, true, true, false);
itConfigs.put(QTIExportMCQItemFormatConfig.class, confMCQ );
}
} else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_KPRIM)){
if (itConfigs.get(QTIExportKPRIMItemFormatConfig.class) == null){
QTIExportKPRIMItemFormatConfig confKPRIM = new QTIExportKPRIMItemFormatConfig(true, true, true, false);
itConfigs.put(QTIExportKPRIMItemFormatConfig.class, confKPRIM);
}
} else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_ESSAY)){
if (itConfigs.get(QTIExportEssayItemFormatConfig.class) == null){
QTIExportEssayItemFormatConfig confEssay = new QTIExportEssayItemFormatConfig(true, false);
itConfigs.put(QTIExportEssayItemFormatConfig.class, confEssay);
}
} else if (item.getItemIdent().startsWith(ItemParser.ITEM_PREFIX_FIB)){
if (itConfigs.get(QTIExportFIBItemFormatConfig.class) == null){
QTIExportFIBItemFormatConfig confFIB = new QTIExportFIBItemFormatConfig(true, true, false);
itConfigs.put(QTIExportFIBItemFormatConfig.class, confFIB);
}
}
//if cannot find the type via the ItemParser, look for the QTIItemObject type
else if (item.getItemType().equals(QTIItemObject.TYPE.A)){
QTIExportEssayItemFormatConfig confEssay = new QTIExportEssayItemFormatConfig(true, false);
itConfigs.put(QTIExportEssayItemFormatConfig.class, confEssay);
} else if (item.getItemType().equals(QTIItemObject.TYPE.R)){
QTIExportSCQItemFormatConfig confSCQ = new QTIExportSCQItemFormatConfig(true, true, true, false);
itConfigs.put(QTIExportSCQItemFormatConfig.class, confSCQ);
} else if (item.getItemType().equals(QTIItemObject.TYPE.C)){
QTIExportMCQItemFormatConfig confMCQ = new QTIExportMCQItemFormatConfig(true, true, true, false);
itConfigs.put(QTIExportMCQItemFormatConfig.class, confMCQ );
} else if (item.getItemType().equals(QTIItemObject.TYPE.B)){
QTIExportFIBItemFormatConfig confFIB = new QTIExportFIBItemFormatConfig(true, true, false);
itConfigs.put(QTIExportFIBItemFormatConfig.class, confFIB);
} else {
throw new OLATRuntimeException(null,"Can not resolve QTIItem type", null);
}
}
return itConfigs;
}
}