fixes
This commit is contained in:
parent
96b6f6efc7
commit
8278f3f43d
11 changed files with 115 additions and 77 deletions
|
@ -8,13 +8,10 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.api;
|
package ch.ethz.seb.sebserver.gbl.api;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -38,23 +35,9 @@ public class POSTMapper {
|
||||||
|
|
||||||
public POSTMapper(final MultiValueMap<String, String> params) {
|
public POSTMapper(final MultiValueMap<String, String> params) {
|
||||||
super();
|
super();
|
||||||
this.params = new LinkedMultiValueMap<>();
|
this.params = params != null
|
||||||
if (params != null) {
|
? new LinkedMultiValueMap<>(params)
|
||||||
for (final Map.Entry<String, List<String>> entry : params.entrySet()) {
|
: new LinkedMultiValueMap<>();
|
||||||
this.params.put(
|
|
||||||
entry.getKey(),
|
|
||||||
entry.getValue()
|
|
||||||
.stream()
|
|
||||||
.map(encoded -> {
|
|
||||||
try {
|
|
||||||
return URLDecoder.decode(encoded, "UTF-8");
|
|
||||||
} catch (final UnsupportedEncodingException e) {
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(final String name) {
|
public String getString(final String name) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Collections;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
@ -27,15 +28,15 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
|
||||||
|
|
||||||
public final class Exam implements GrantEntity, Activatable {
|
public final class Exam implements GrantEntity, Activatable {
|
||||||
|
|
||||||
|
public static final String ATTR_STATUS = "examStatus";
|
||||||
public static final String FILTER_ATTR_TYPE = "type";
|
public static final String FILTER_ATTR_TYPE = "type";
|
||||||
public static final String FILTER_ATTR_FROM = "from";
|
public static final String FILTER_ATTR_FROM = "from";
|
||||||
|
|
||||||
// public enum ExamStatus {
|
public enum ExamStatus {
|
||||||
// ON_CREATION,
|
UP_COMING,
|
||||||
// READY,
|
RUNNING,
|
||||||
// RUNNING,
|
FINISHED
|
||||||
// FINISHED
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
public enum ExamType {
|
public enum ExamType {
|
||||||
UNDEFINED,
|
UNDEFINED,
|
||||||
|
@ -82,7 +83,6 @@ public final class Exam implements GrantEntity, Activatable {
|
||||||
public final String quitPassword;
|
public final String quitPassword;
|
||||||
|
|
||||||
@JsonProperty(EXAM.ATTR_OWNER)
|
@JsonProperty(EXAM.ATTR_OWNER)
|
||||||
@NotNull
|
|
||||||
public final String owner;
|
public final String owner;
|
||||||
|
|
||||||
@JsonProperty(EXAM.ATTR_SUPPORTER)
|
@JsonProperty(EXAM.ATTR_SUPPORTER)
|
||||||
|
@ -221,6 +221,24 @@ public final class Exam implements GrantEntity, Activatable {
|
||||||
return this.quitPassword;
|
return this.quitPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public ExamStatus getStatus() {
|
||||||
|
if (this.startTime == null) {
|
||||||
|
return ExamStatus.UP_COMING;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||||
|
if (this.startTime.isBefore(now)) {
|
||||||
|
if (this.endTime == null || this.endTime.isAfter(now)) {
|
||||||
|
return ExamStatus.RUNNING;
|
||||||
|
} else {
|
||||||
|
return ExamStatus.FINISHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExamStatus.UP_COMING;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return this.active;
|
return this.active;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
@ -40,10 +41,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ActivateExam;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeactivateExam;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicator;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicator;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicators;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicators;
|
||||||
|
@ -128,8 +126,9 @@ public class ExamForm implements TemplateComposer {
|
||||||
final BooleanSupplier isNew = () -> importFromQuizData;
|
final BooleanSupplier isNew = () -> importFromQuizData;
|
||||||
final BooleanSupplier isNotNew = () -> !isNew.getAsBoolean();
|
final BooleanSupplier isNotNew = () -> !isNew.getAsBoolean();
|
||||||
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(exam);
|
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(exam);
|
||||||
final boolean writeGrant = userGrantCheck.w();
|
|
||||||
final boolean modifyGrant = userGrantCheck.m();
|
final boolean modifyGrant = userGrantCheck.m();
|
||||||
|
final ExamStatus examStatus = exam.getStatus();
|
||||||
|
final boolean editable = examStatus == ExamStatus.UP_COMING;
|
||||||
|
|
||||||
// The Exam form
|
// The Exam form
|
||||||
final FormHandle<Exam> formHandle = this.pageService.formBuilder(
|
final FormHandle<Exam> formHandle = this.pageService.formBuilder(
|
||||||
|
@ -191,6 +190,11 @@ public class ExamForm implements TemplateComposer {
|
||||||
"sebserver.exam.form.type",
|
"sebserver.exam.form.type",
|
||||||
String.valueOf(exam.type),
|
String.valueOf(exam.type),
|
||||||
this.resourceService::examTypeResources))
|
this.resourceService::examTypeResources))
|
||||||
|
.addField(FormBuilder.text(
|
||||||
|
Exam.ATTR_STATUS,
|
||||||
|
"sebserver.exam.form.status",
|
||||||
|
i18nSupport.getText(new LocTextKey("sebserver.exam.status." + examStatus.name())))
|
||||||
|
.readonly(true))
|
||||||
.addField(FormBuilder.multiComboSelection(
|
.addField(FormBuilder.multiComboSelection(
|
||||||
Domain.EXAM.ATTR_SUPPORTER,
|
Domain.EXAM.ATTR_SUPPORTER,
|
||||||
"sebserver.exam.form.supporter",
|
"sebserver.exam.form.supporter",
|
||||||
|
@ -210,7 +214,7 @@ public class ExamForm implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_MODIFY)
|
.newAction(ActionDefinition.EXAM_MODIFY)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.publishIf(() -> modifyGrant && readonly)
|
.publishIf(() -> modifyGrant && readonly && editable)
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_SAVE)
|
.newAction(ActionDefinition.EXAM_SAVE)
|
||||||
.withExec(formHandle::processFormSave)
|
.withExec(formHandle::processFormSave)
|
||||||
|
@ -221,18 +225,18 @@ public class ExamForm implements TemplateComposer {
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, String.valueOf(importFromQuizData))
|
.withAttribute(AttributeKeys.IMPORT_FROM_QUIZZ_DATA, String.valueOf(importFromQuizData))
|
||||||
.withExec(this::cancelModify)
|
.withExec(this::cancelModify)
|
||||||
.publishIf(() -> !readonly)
|
.publishIf(() -> !readonly);
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_DEACTIVATE)
|
// .newAction(ActionDefinition.EXAM_DEACTIVATE)
|
||||||
.withEntityKey(entityKey)
|
// .withEntityKey(entityKey)
|
||||||
.withSimpleRestCall(restService, DeactivateExam.class)
|
// .withSimpleRestCall(restService, DeactivateExam.class)
|
||||||
.withConfirm(PageUtils.confirmDeactivation(exam, restService))
|
// .withConfirm(PageUtils.confirmDeactivation(exam, restService))
|
||||||
.publishIf(() -> writeGrant && readonly && exam.isActive())
|
// .publishIf(() -> writeGrant && readonly && exam.isActive())
|
||||||
|
//
|
||||||
.newAction(ActionDefinition.EXAM_ACTIVATE)
|
// .newAction(ActionDefinition.EXAM_ACTIVATE)
|
||||||
.withEntityKey(entityKey)
|
// .withEntityKey(entityKey)
|
||||||
.withSimpleRestCall(restService, ActivateExam.class)
|
// .withSimpleRestCall(restService, ActivateExam.class)
|
||||||
.publishIf(() -> writeGrant && readonly && !exam.isActive());
|
// .publishIf(() -> writeGrant && readonly && !exam.isActive());
|
||||||
|
|
||||||
// additional data in read-only view
|
// additional data in read-only view
|
||||||
if (readonly) {
|
if (readonly) {
|
||||||
|
@ -274,17 +278,17 @@ public class ExamForm implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_INDICATOR_NEW)
|
.newAction(ActionDefinition.EXAM_INDICATOR_NEW)
|
||||||
.withParentEntityKey(entityKey)
|
.withParentEntityKey(entityKey)
|
||||||
.publishIf(() -> modifyGrant)
|
.publishIf(() -> modifyGrant && editable)
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.EXAM_INDICATOR_MODIFY_FROM_LIST)
|
||||||
.withParentEntityKey(entityKey)
|
.withParentEntityKey(entityKey)
|
||||||
.withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
|
.withSelect(indicatorTable::getSelection, PageAction::applySingleSelection, emptySelectionTextKey)
|
||||||
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent())
|
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent() && editable)
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST)
|
.newAction(ActionDefinition.EXAM_INDICATOR_DELETE_FROM_LIST)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withSelect(indicatorTable::getSelection, this::deleteSelectedIndicator, emptySelectionTextKey)
|
.withSelect(indicatorTable::getSelection, this::deleteSelectedIndicator, emptySelectionTextKey)
|
||||||
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent());
|
.publishIf(() -> modifyGrant && indicatorTable.hasAnyContent() && editable);
|
||||||
|
|
||||||
// TODO List of attached SEB Configurations
|
// TODO List of attached SEB Configurations
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ package ch.ethz.seb.sebserver.gui.content;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -27,6 +29,7 @@ import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.PageMessageException;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
|
@ -60,6 +63,8 @@ public class QuizDiscoveryList implements TemplateComposer {
|
||||||
new LocTextKey("sebserver.quizdiscovery.list.column.name");
|
new LocTextKey("sebserver.quizdiscovery.list.column.name");
|
||||||
private final static LocTextKey DETAILS_TITLE_TEXT_KEY =
|
private final static LocTextKey DETAILS_TITLE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.quizdiscovery.quiz.details.title");
|
new LocTextKey("sebserver.quizdiscovery.quiz.details.title");
|
||||||
|
private final static LocTextKey NO_IMPORT_OF_OUT_DATED_QUIZ =
|
||||||
|
new LocTextKey("sebserver.quizdiscovery.quiz.import.out.dated");
|
||||||
|
|
||||||
// filter attribute models
|
// filter attribute models
|
||||||
private final TableFilterAttribute lmsFilter;
|
private final TableFilterAttribute lmsFilter;
|
||||||
|
@ -174,6 +179,13 @@ public class QuizDiscoveryList implements TemplateComposer {
|
||||||
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
|
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
|
||||||
final QuizData selectedROWData = table.getSelectedROWData();
|
final QuizData selectedROWData = table.getSelectedROWData();
|
||||||
|
|
||||||
|
if (selectedROWData.endTime != null) {
|
||||||
|
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||||
|
if (selectedROWData.endTime.isBefore(now)) {
|
||||||
|
throw new PageMessageException(NO_IMPORT_OF_OUT_DATED_QUIZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return action
|
return action
|
||||||
.withEntityKey(action.getSingleSelection())
|
.withEntityKey(action.getSingleSelection())
|
||||||
.withParentEntityKey(new EntityKey(selectedROWData.lmsSetupId, EntityType.LMS_SETUP))
|
.withParentEntityKey(new EntityKey(selectedROWData.lmsSetupId, EntityType.LMS_SETUP))
|
||||||
|
@ -196,7 +208,8 @@ public class QuizDiscoveryList implements TemplateComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createDetailsForm(final QuizData quizData, final PageContext pc) {
|
private void createDetailsForm(final QuizData quizData, final PageContext pc) {
|
||||||
this.pageService.formBuilder(pc, 4)
|
this.pageService.formBuilder(pc, 3)
|
||||||
|
.withEmptyCellSeparation(false)
|
||||||
.readonly(true)
|
.readonly(true)
|
||||||
.addField(FormBuilder.singleSelection(
|
.addField(FormBuilder.singleSelection(
|
||||||
QuizData.QUIZ_ATTR_LMS_SETUP_ID,
|
QuizData.QUIZ_ATTR_LMS_SETUP_ID,
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.form;
|
package ch.ethz.seb.sebserver.gui.form;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -266,11 +268,11 @@ public final class Form implements FormBinding {
|
||||||
final String[] nameValue = StringUtils.split(split[i], Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR);
|
final String[] nameValue = StringUtils.split(split[i], Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR);
|
||||||
buffer.append(nameValue[0])
|
buffer.append(nameValue[0])
|
||||||
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
|
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
|
||||||
.append(nameValue[1]);
|
.append(URLEncoder.encode(nameValue[1], StandardCharsets.UTF_8));
|
||||||
} else {
|
} else {
|
||||||
buffer.append(name)
|
buffer.append(name)
|
||||||
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
|
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
|
||||||
.append(split[i]);
|
.append(URLEncoder.encode(split[i], StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class ModalInputDialog<T> extends Dialog {
|
||||||
shell.pack();
|
shell.pack();
|
||||||
final Rectangle bounds = shell.getBounds();
|
final Rectangle bounds = shell.getBounds();
|
||||||
final Rectangle bounds2 = super.getParent().getDisplay().getBounds();
|
final Rectangle bounds2 = super.getParent().getDisplay().getBounds();
|
||||||
bounds.width = 400;
|
//bounds.width = bounds.width;
|
||||||
bounds.x = (bounds2.width - bounds.width) / 2;
|
bounds.x = (bounds2.width - bounds.width) / 2;
|
||||||
bounds.y = (bounds2.height - bounds.height) / 2;
|
bounds.y = (bounds2.height - bounds.height) / 2;
|
||||||
shell.setBounds(bounds);
|
shell.setBounds(bounds);
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -199,7 +200,7 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
null,
|
null,
|
||||||
(exam.type != null) ? exam.type.name() : ExamType.UNDEFINED.name(),
|
(exam.type != null) ? exam.type.name() : ExamType.UNDEFINED.name(),
|
||||||
null,
|
null,
|
||||||
BooleanUtils.toInteger(false));
|
BooleanUtils.toInteger(true));
|
||||||
|
|
||||||
this.examRecordMapper.insert(examRecord);
|
this.examRecordMapper.insert(examRecord);
|
||||||
return examRecord;
|
return examRecord;
|
||||||
|
@ -353,29 +354,35 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
|
|
||||||
private Result<Collection<Exam>> toDomainModel(final Long lmsSetupId, final Collection<ExamRecord> records) {
|
private Result<Collection<Exam>> toDomainModel(final Long lmsSetupId, final Collection<ExamRecord> records) {
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
final HashMap<String, ExamRecord> recordMapping = records
|
|
||||||
.stream()
|
|
||||||
.reduce(new HashMap<String, ExamRecord>(),
|
|
||||||
(map, record) -> Utils.mapPut(map, record.getExternalId(), record),
|
|
||||||
(map1, map2) -> Utils.mapPutAll(map1, map2));
|
|
||||||
|
|
||||||
return this.lmsAPIService
|
// map records
|
||||||
|
final Map<String, ExamRecord> recordMapping = records
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(r -> r.getExternalId(), Function.identity()));
|
||||||
|
|
||||||
|
// get and map quizzes
|
||||||
|
final Map<String, QuizData> quizzes = this.lmsAPIService
|
||||||
.getLmsAPITemplate(lmsSetupId)
|
.getLmsAPITemplate(lmsSetupId)
|
||||||
.map(template -> template.getQuizzes(recordMapping.keySet()))
|
.map(template -> template.getQuizzes(recordMapping.keySet()))
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.map(result -> result.flatMap(quiz -> toDomainModel(recordMapping, quiz)).getOrThrow())
|
.flatMap(Result::skipOnError)
|
||||||
|
.collect(Collectors.toMap(q -> q.id, Function.identity()));
|
||||||
|
|
||||||
|
// collect Exam's
|
||||||
|
return recordMapping.entrySet()
|
||||||
|
.stream()
|
||||||
|
.map(entry -> toDomainModel(entry.getValue(), quizzes.get(entry.getKey())).getOrThrow())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<Exam> toDomainModel(
|
private Result<Exam> toDomainModel(
|
||||||
final HashMap<String, ExamRecord> recordMapping,
|
final ExamRecord record,
|
||||||
final QuizData quizData) {
|
final QuizData quizData) {
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
|
|
||||||
final ExamRecord record = recordMapping.get(quizData.id);
|
|
||||||
final Collection<String> supporter = (StringUtils.isNoneBlank(record.getSupporter()))
|
final Collection<String> supporter = (StringUtils.isNoneBlank(record.getSupporter()))
|
||||||
? Arrays.asList(StringUtils.split(record.getSupporter(), Constants.LIST_SEPARATOR_CHAR))
|
? Arrays.asList(StringUtils.split(record.getSupporter(), Constants.LIST_SEPARATOR_CHAR))
|
||||||
: null;
|
: null;
|
||||||
|
@ -384,17 +391,17 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
record.getId(),
|
record.getId(),
|
||||||
record.getInstitutionId(),
|
record.getInstitutionId(),
|
||||||
record.getLmsSetupId(),
|
record.getLmsSetupId(),
|
||||||
quizData.id,
|
record.getExternalId(),
|
||||||
quizData.name,
|
(quizData != null) ? quizData.name : Constants.EMPTY_NOTE,
|
||||||
quizData.description,
|
(quizData != null) ? quizData.description : Constants.EMPTY_NOTE,
|
||||||
quizData.startTime,
|
(quizData != null) ? quizData.startTime : null,
|
||||||
quizData.endTime,
|
(quizData != null) ? quizData.endTime : null,
|
||||||
quizData.startURL,
|
(quizData != null) ? quizData.startURL : Constants.EMPTY_NOTE,
|
||||||
ExamType.valueOf(record.getType()),
|
ExamType.valueOf(record.getType()),
|
||||||
record.getQuitPassword(),
|
record.getQuitPassword(),
|
||||||
record.getOwner(),
|
record.getOwner(),
|
||||||
supporter,
|
supporter,
|
||||||
BooleanUtils.toBooleanObject(record.getActive()));
|
BooleanUtils.toBooleanObject((quizData != null) ? record.getActive() : 0));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||||
|
@ -64,12 +63,12 @@ public interface LmsAPIService {
|
||||||
public static Predicate<QuizData> quizFilterFunction(final FilterMap filterMap) {
|
public static Predicate<QuizData> quizFilterFunction(final FilterMap filterMap) {
|
||||||
final String name = filterMap.getQuizName();
|
final String name = filterMap.getQuizName();
|
||||||
final DateTime from = filterMap.getQuizFromTime();
|
final DateTime from = filterMap.getQuizFromTime();
|
||||||
final DateTime now = DateTime.now(DateTimeZone.UTC);
|
//final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||||
return q -> {
|
return q -> {
|
||||||
final boolean nameFilter = StringUtils.isBlank(name) || (q.name != null && q.name.contains(name));
|
final boolean nameFilter = StringUtils.isBlank(name) || (q.name != null && q.name.contains(name));
|
||||||
final boolean startTimeFilter = (from == null) || (q.startTime != null && q.startTime.isAfter(from));
|
final boolean startTimeFilter = (from == null) || (q.startTime != null && q.startTime.isAfter(from));
|
||||||
final boolean endTimeFilter = (now == null) || (q.endTime != null && q.endTime.isAfter(now));
|
// final boolean endTimeFilter = (now == null) || (q.endTime != null && q.endTime.isAfter(now));
|
||||||
return nameFilter && startTimeFilter && endTimeFilter;
|
return nameFilter && startTimeFilter /* && endTimeFilter */;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,13 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -93,7 +95,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
||||||
this.knownTokenAccessPaths.addAll(Arrays.asList(alternativeTokenRequestPaths));
|
this.knownTokenAccessPaths.addAll(Arrays.asList(alternativeTokenRequestPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.allQuizzesSupplier = asyncService.createMemoizingCircuitBreaker(allQuizzesSupplier(lmsSetup));
|
this.allQuizzesSupplier = asyncService.createMemoizingCircuitBreaker(allQuizzesSupplier());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -143,8 +145,13 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
||||||
// TODO Auto-generated method stub
|
// TODO this can be improved in the future
|
||||||
return null;
|
return getQuizzes(new FilterMap())
|
||||||
|
.getOrElse(() -> Collections.emptyList())
|
||||||
|
.stream()
|
||||||
|
.filter(quiz -> ids.contains(quiz.id))
|
||||||
|
.map(quiz -> Result.of(quiz))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<LmsSetup> initRestTemplateAndRequestAccessToken() {
|
private Result<LmsSetup> initRestTemplateAndRequestAccessToken() {
|
||||||
|
@ -209,7 +216,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<List<QuizData>> allQuizzesSupplier(final LmsSetup lmsSetup) {
|
private Supplier<List<QuizData>> allQuizzesSupplier() {
|
||||||
return () -> {
|
return () -> {
|
||||||
return initRestTemplateAndRequestAccessToken()
|
return initRestTemplateAndRequestAccessToken()
|
||||||
.map(this::collectAllQuizzes)
|
.map(this::collectAllQuizzes)
|
||||||
|
|
|
@ -210,6 +210,7 @@ sebserver.quizdiscovery.info.pleaseSelect=Please Select a Quiz first
|
||||||
|
|
||||||
sebserver.quizdiscovery.action.list=Quiz Discovery
|
sebserver.quizdiscovery.action.list=Quiz Discovery
|
||||||
sebserver.quizdiscovery.action.import=Import as Exam
|
sebserver.quizdiscovery.action.import=Import as Exam
|
||||||
|
sebserver.quizdiscovery.quiz.import.out.dated=The Selected Quiz is in the past and can't be imported
|
||||||
sebserver.quizdiscovery.action.details=Show Details
|
sebserver.quizdiscovery.action.details=Show Details
|
||||||
|
|
||||||
sebserver.quizdiscovery.quiz.details.title=Quiz Details
|
sebserver.quizdiscovery.quiz.details.title=Quiz Details
|
||||||
|
@ -262,6 +263,10 @@ sebserver.exam.type.MANAGED=Managed
|
||||||
sebserver.exam.type.BYOD=Bring Your Own Device
|
sebserver.exam.type.BYOD=Bring Your Own Device
|
||||||
sebserver.exam.type.VDI=VDI (Virtual Desktop Infrastructure)
|
sebserver.exam.type.VDI=VDI (Virtual Desktop Infrastructure)
|
||||||
|
|
||||||
|
sebserver.exam.status.UP_COMING=Up Coming
|
||||||
|
sebserver.exam.status.RUNNING=Running
|
||||||
|
sebserver.exam.status.FINISHED=Finished
|
||||||
|
|
||||||
sebserver.exam.indicator.list.actions=Selected Indicator
|
sebserver.exam.indicator.list.actions=Selected Indicator
|
||||||
sebserver.exam.indicator.list.title=Indicators
|
sebserver.exam.indicator.list.title=Indicators
|
||||||
sebserver.exam.indicator.list.column.type=Type
|
sebserver.exam.indicator.list.column.type=Type
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class QuizDataTest extends AdministrationAPIIntegrationTester {
|
||||||
});
|
});
|
||||||
|
|
||||||
assertNotNull(quizzes);
|
assertNotNull(quizzes);
|
||||||
assertTrue(quizzes.content.size() == 5);
|
assertTrue(quizzes.content.size() == 7);
|
||||||
|
|
||||||
// for the inactive LmsSetup we should'nt get any quizzes
|
// for the inactive LmsSetup we should'nt get any quizzes
|
||||||
quizzes = new RestAPITestHelper()
|
quizzes = new RestAPITestHelper()
|
||||||
|
@ -110,7 +110,7 @@ public class QuizDataTest extends AdministrationAPIIntegrationTester {
|
||||||
});
|
});
|
||||||
|
|
||||||
assertNotNull(quizzes);
|
assertNotNull(quizzes);
|
||||||
assertTrue(quizzes.content.size() == 5);
|
assertTrue(quizzes.content.size() == 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Add table
Reference in a new issue