Newer
Older
/**
* <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.course.nodes;
import static org.olat.modules.forms.EvaluationFormSurveyIdentifier.of;

uhensler
committed
import java.io.File;
import java.util.List;

uhensler
committed
import java.util.Locale;
import java.util.zip.ZipOutputStream;
import org.apache.logging.log4j.Logger;

uhensler
committed
import org.olat.core.CoreSpringFactory;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.stack.BreadcrumbPanel;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.tabbable.TabbableController;

uhensler
committed
import org.olat.core.id.Identity;
import org.olat.core.id.Organisation;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.core.util.Util;
import org.olat.course.ICourse;
import org.olat.course.condition.ConditionEditController;
import org.olat.course.editor.CourseEditorEnv;
import org.olat.course.editor.NodeEditController;
import org.olat.course.editor.StatusDescription;

uhensler
committed
import org.olat.course.export.CourseEnvironmentMapper;
import org.olat.course.nodes.survey.SurveyEditController;
import org.olat.course.nodes.survey.SurveyRunController;

uhensler
committed
import org.olat.course.nodes.survey.SurveyRunSecurityCallback;
import org.olat.course.nodes.survey.SurveyStatisticResourceResult;
import org.olat.course.run.navigation.NodeRunConstructionResult;
import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.course.statistic.StatisticResourceOption;
import org.olat.course.statistic.StatisticResourceResult;
import org.olat.course.statistic.StatisticType;
import org.olat.modules.ModuleConfiguration;

uhensler
committed
import org.olat.modules.forms.EvaluationFormManager;
import org.olat.modules.forms.EvaluationFormSurvey;
import org.olat.modules.forms.EvaluationFormSurveyIdentifier;
import org.olat.modules.forms.SessionFilter;
import org.olat.modules.forms.SessionFilterFactory;

uhensler
committed
import org.olat.modules.forms.handler.EvaluationFormResource;
import org.olat.modules.forms.model.xml.Form;
import org.olat.modules.forms.ui.EvaluationFormExcelExport;
import org.olat.modules.forms.ui.LegendNameGenerator;
import org.olat.modules.forms.ui.ReportHelper;
import org.olat.modules.forms.ui.SessionInformationLegendNameGenerator;
import org.olat.repository.RepositoryEntry;

uhensler
committed
import org.olat.repository.RepositoryEntryImportExport;
import org.olat.repository.RepositoryManager;

uhensler
committed
import org.olat.repository.handlers.RepositoryHandler;
import org.olat.repository.handlers.RepositoryHandlerFactory;
/**
*
* Initial date: 23.04.2018<br>
* @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
*
*/
public class SurveyCourseNode extends AbstractAccessableCourseNode {
private static final Logger log = Tracing.createLoggerFor(SurveyCourseNode.class);
private static final long serialVersionUID = 905046067514602922L;
public static final String SURVEY_ICON = "o_survey_icon";
private static final String TYPE = "survey";
public static final int CURRENT_VERSION = 1;
public static final String CONFIG_KEY_REPOSITORY_SOFTKEY = "repository.softkey";

uhensler
committed
public static final String CONFIG_KEY_EXECUTION_BY_OWNER = "execution.by.owner";
public static final String CONFIG_KEY_EXECUTION_BY_COACH = "execution.by.coach";
public static final String CONFIG_KEY_EXECUTION_BY_PARTICIPANT = "execution.by.participant";
public static final String CONFIG_KEY_EXECUTION_BY_GUEST = "execution.by.guest";
public static final String CONFIG_KEY_REPORT_FOR_OWNER = "report.for.owner";
public static final String CONFIG_KEY_REPORT_FOR_COACH = "report.for.coach";
public static final String CONFIG_KEY_REPORT_FOR_PARTICIPANT = "report.for.participant";
public static final String CONFIG_KEY_REPORT_FOR_GUEST = "report.for.guest";
public SurveyCourseNode() {
super(TYPE);
updateModuleConfigDefaults(true);
}
@Override
public RepositoryEntry getReferencedRepositoryEntry() {

uhensler
committed
return getEvaluationForm(getModuleConfiguration());
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
}
@Override
public boolean needsReferenceToARepositoryEntry() {
return true;
}
@SuppressWarnings("deprecation")
@Override
public StatusDescription isConfigValid() {
if (oneClickStatusCache != null) {
return oneClickStatusCache[0];
}
StatusDescription sd = StatusDescription.NOERROR;
String repoKey = getModuleConfiguration().getStringValue(CONFIG_KEY_REPOSITORY_SOFTKEY);
boolean repoKeyMissing = !StringHelper.containsNonWhitespace(repoKey);
if (repoKeyMissing) {
String shortKey = "error.repo.no.key.short";
String longKey = "error.repo.no.key.long";
String[] params = new String[] { this.getShortTitle() };
String translPackage = Util.getPackageName(SurveyEditController.class);
sd = new StatusDescription(StatusDescription.ERROR, shortKey, longKey, params, translPackage);
sd.setDescriptionForUnit(getIdent());
// set which pane is affected by error
sd.setActivateableViewIdentifier(SurveyEditController.PANE_TAB_CONFIG);
}
return sd;
}
@Override
public TabbableController createEditController(UserRequest ureq, WindowControl wControl, BreadcrumbPanel stackPanel,
ICourse course, UserCourseEnvironment euce) {
updateModuleConfigDefaults(false);
TabbableController childTabCntrllr = new SurveyEditController(ureq, wControl, this, course, euce);
CourseNode chosenNode = course.getEditorTreeModel().getCourseNode(euce.getCourseEditorEnv().getCurrentCourseNodeId());
return new NodeEditController(ureq, wControl, course.getEditorTreeModel(), course, chosenNode, euce, childTabCntrllr);
}
@Override
public NodeRunConstructionResult createNodeRunConstructionResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) {

uhensler
committed
SurveyRunSecurityCallback secCallback = new SurveyRunSecurityCallback(getModuleConfiguration(), userCourseEnv);
Controller runCtrl = new SurveyRunController(ureq, wControl, userCourseEnv, this, secCallback);
Controller ctrl = TitledWrapperHelper.getWrapper(ureq, wControl, runCtrl, this, SURVEY_ICON);
return new NodeRunConstructionResult(ctrl);
}

uhensler
committed
@Override
public Controller createPreviewController(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, NodeEvaluation ne) {
return createNodeRunConstructionResult(ureq, wControl, userCourseEnv, ne, null).getRunController();
}
@Override
public StatisticResourceResult createStatisticNodeResult(UserRequest ureq, WindowControl wControl,
UserCourseEnvironment userCourseEnv, StatisticResourceOption options, StatisticType type) {
if (isStatisticAllowed(type)) {
RepositoryEntry ores = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry();
SurveyRunSecurityCallback secCallback = new SurveyRunSecurityCallback(getModuleConfiguration(), userCourseEnv);
Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity();
return new SurveyStatisticResourceResult(of(ores, getIdent()), identity, secCallback);
}
return null;
}
@Override
public boolean isStatisticNodeResultAvailable(UserCourseEnvironment userCourseEnv, StatisticType type) {
return isStatisticAllowed(type);
}
private boolean isStatisticAllowed(StatisticType type) {
if(StatisticType.SURVEY.equals(type)) {
return true;
}
return false;
}
@SuppressWarnings("deprecation")
@Override
public StatusDescription[] isConfigValid(CourseEditorEnv cev) {
String translatorStr = Util.getPackageName(ConditionEditController.class);
List<StatusDescription> statusDescs = isConfigValidWithTranslator(cev, translatorStr, getConditionExpressions());
return StatusDescriptionHelper.sort(statusDescs);
}
@Override
public void updateModuleConfigDefaults(boolean isNewNode) {
ModuleConfiguration config = getModuleConfiguration();
if (isNewNode) {
config.setBooleanEntry(CONFIG_KEY_EXECUTION_BY_OWNER, false);
config.setBooleanEntry(CONFIG_KEY_EXECUTION_BY_COACH, false);

uhensler
committed
config.setBooleanEntry(CONFIG_KEY_EXECUTION_BY_PARTICIPANT, true);
config.setBooleanEntry(CONFIG_KEY_EXECUTION_BY_GUEST, false);
config.setBooleanEntry(CONFIG_KEY_REPORT_FOR_OWNER, false);

uhensler
committed
config.setBooleanEntry(CONFIG_KEY_REPORT_FOR_COACH, true);
config.setBooleanEntry(CONFIG_KEY_REPORT_FOR_PARTICIPANT, false);
config.setBooleanEntry(CONFIG_KEY_REPORT_FOR_GUEST, false);
}
config.setConfigurationVersion(CURRENT_VERSION);
}

uhensler
committed
@Override
public void exportNode(File exportDirectory, ICourse course) {
RepositoryEntry re = getEvaluationForm(getModuleConfiguration());
if (re == null) return;
File fExportDirectory = new File(exportDirectory, getIdent());
fExportDirectory.mkdirs();
RepositoryEntryImportExport reie = new RepositoryEntryImportExport(re, fExportDirectory);
reie.exportDoExport();
}

uhensler
committed
@Override
public void importNode(File importDirectory, ICourse course, Identity owner, Organisation organisation, Locale locale, boolean withReferences) {
RepositoryEntryImportExport rie = new RepositoryEntryImportExport(importDirectory, getIdent());
if(withReferences && rie.anyExportedPropertiesAvailable()) {
RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(EvaluationFormResource.TYPE_NAME);
RepositoryEntry re = handler.importResource(owner, rie.getInitialAuthor(), rie.getDisplayName(),
rie.getDescription(), false, organisation, locale, rie.importGetExportedFile(), null);
setEvaluationFormReference(re, getModuleConfiguration());
postImportCopy(course, getIdent());

uhensler
committed
} else {
removeEvaluationFormReference(getModuleConfiguration());
}
}

uhensler
committed
@Override
public void postCopy(CourseEnvironmentMapper envMapper, Processing processType, ICourse course, ICourse sourceCrourse) {
super.postCopy(envMapper, processType, course, sourceCrourse);
postImportCopy(course, getIdent());

uhensler
committed
}
@Override
public CourseNode createInstanceForCopy(boolean isNewTitle, ICourse course, Identity author) {
CourseNode copyInstance = super.createInstanceForCopy(isNewTitle, course, author);
postImportCopy(course, copyInstance.getIdent());
return copyInstance;
}

uhensler
committed
private void postImportCopy(ICourse course, String nodeIdent) {

uhensler
committed
RepositoryEntry ores = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
EvaluationFormManager evaluationFormManager = CoreSpringFactory.getImpl(EvaluationFormManager.class);
RepositoryEntry formEntry = getEvaluationForm(getModuleConfiguration());
EvaluationFormSurveyIdentifier surveyIdent = of(ores, nodeIdent);
EvaluationFormSurvey survey = evaluationFormManager.loadSurvey(surveyIdent);

uhensler
committed
if (survey == null) {
survey = evaluationFormManager.createSurvey(surveyIdent, formEntry);

uhensler
committed
} else {
boolean isFormUpdateable = evaluationFormManager.isFormUpdateable(survey);
if (isFormUpdateable) {
survey = evaluationFormManager.updateSurveyForm(survey, formEntry);
}
}
}
public boolean archiveNodeData(Locale locale, ICourse course, ArchiveOptions options,
ZipOutputStream exportStream, String archivePath, String charset) {
EvaluationFormManager evaluationFormManager = CoreSpringFactory.getImpl(EvaluationFormManager.class);
RepositoryEntry ores = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
EvaluationFormSurvey survey = evaluationFormManager.loadSurvey(of(ores, getIdent()));
SessionFilter filter = SessionFilterFactory.createSelectDone(survey);
Form form = evaluationFormManager.loadForm(survey.getFormEntry());
LegendNameGenerator legendNameGenerator = new SessionInformationLegendNameGenerator(filter);
ReportHelper reportHelper = ReportHelper.builder(locale).withLegendNameGenrator(legendNameGenerator).build();
EvaluationFormExcelExport evaluationFormExport = new EvaluationFormExcelExport(form, filter, reportHelper,
getShortName());
evaluationFormExport.export(exportStream, archivePath);
} catch (IOException e) {
log.error("", e);
return false;
}
return true;
}

uhensler
committed
@Override
public void cleanupOnDelete(ICourse course) {
super.cleanupOnDelete(course);
EvaluationFormManager evaluationFormManager = CoreSpringFactory.getImpl(EvaluationFormManager.class);
RepositoryEntry ores = RepositoryManager.getInstance().lookupRepositoryEntry(course, true);
EvaluationFormSurvey survey = evaluationFormManager.loadSurvey(of(ores, getIdent()));
evaluationFormManager.deleteSurvey(survey);
}

uhensler
committed
public static RepositoryEntry getEvaluationForm(ModuleConfiguration config) {
if (config == null) return null;
String repoSoftkey = config.getStringValue(CONFIG_KEY_REPOSITORY_SOFTKEY);
if (!StringHelper.containsNonWhitespace(repoSoftkey)) return null;
return RepositoryManager.getInstance().lookupRepositoryEntryBySoftkey(repoSoftkey, false);
}

uhensler
committed
public static void setEvaluationFormReference(RepositoryEntry re, ModuleConfiguration moduleConfig) {
moduleConfig.set(CONFIG_KEY_REPOSITORY_SOFTKEY, re.getSoftkey());
}
public static void removeEvaluationFormReference(ModuleConfiguration moduleConfig) {
moduleConfig.remove(CONFIG_KEY_REPOSITORY_SOFTKEY);
}