|
|
|
|
@ -25,6 +25,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
@ -36,7 +37,6 @@ import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.UUID;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
@ -70,7 +70,15 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
|
|
|
|
|
private boolean trainingTaskClassConfigTableChecked = false;
|
|
|
|
|
private volatile boolean defaultTasksInitialized = false;
|
|
|
|
|
private final Object defaultTasksInitializationLock = new Object();
|
|
|
|
|
private final Set<String> initializedStudentClassTaskIds = ConcurrentHashMap.newKeySet();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Seed built-in task definitions during application startup so that opening
|
|
|
|
|
* a student's navigation never performs the initialization write path.
|
|
|
|
|
*/
|
|
|
|
|
@PostConstruct
|
|
|
|
|
public void initializeDefaultTasksAtStartup() {
|
|
|
|
|
ensureDefaultTasks(null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<TrainingTask> list(String projectName, String taskName, Boolean enabledOnly) {
|
|
|
|
|
@ -315,7 +323,6 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
|
|
|
|
|
|| (requiresExplicitPublication(normalizedTaskKey) && publishedTaskKeys == null)) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
ensureStudentClassTasksInitialized(teachingClassId);
|
|
|
|
|
TrainingTaskClassConfig classTask = trainingTaskClassConfigMapper.selectByTeachingClassAndTaskKey(teachingClassId, normalizedTaskKey);
|
|
|
|
|
if (classTask != null) {
|
|
|
|
|
return Boolean.TRUE.equals(classTask.getEnabled()) ? toTask(classTask) : null;
|
|
|
|
|
@ -345,8 +352,7 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
|
|
|
|
|
.filter(task -> !requiresExplicitPublication(task.getTaskKey()))
|
|
|
|
|
.collect(Collectors.toList()), enabledOnly);
|
|
|
|
|
}
|
|
|
|
|
List<TrainingTaskClassConfig> classTasks = readStudentClassTasks(teachingClassId, defaults);
|
|
|
|
|
List<TrainingTask> tasks = filterEnabled(toTasks(classTasks), enabledOnly);
|
|
|
|
|
List<TrainingTask> tasks = filterEnabled(readClassTasks(teachingClassId, defaults), enabledOnly);
|
|
|
|
|
Set<String> publishedTaskKeys = getPublishedTaskKeys(teachingClassId);
|
|
|
|
|
if (publishedTaskKeys == null) {
|
|
|
|
|
return tasks.stream()
|
|
|
|
|
@ -487,23 +493,6 @@ public class TrainingTaskServiceImpl implements TrainingTaskService {
|
|
|
|
|
return new ArrayList<>(existingByKey.values());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ensureStudentClassTasksInitialized(String teachingClassId) {
|
|
|
|
|
if (StringUtils.isBlank(teachingClassId) || initializedStudentClassTaskIds.contains(teachingClassId)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ensureClassTasksInitialized(teachingClassId, trainingTaskMapper.selectList(null, null, null), null);
|
|
|
|
|
initializedStudentClassTaskIds.add(teachingClassId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<TrainingTaskClassConfig> readStudentClassTasks(String teachingClassId, List<TrainingTask> defaults) {
|
|
|
|
|
if (initializedStudentClassTaskIds.contains(teachingClassId)) {
|
|
|
|
|
return trainingTaskClassConfigMapper.selectListByTeachingClass(teachingClassId, null);
|
|
|
|
|
}
|
|
|
|
|
List<TrainingTaskClassConfig> classTasks = ensureClassTasksInitialized(teachingClassId, defaults, null);
|
|
|
|
|
initializedStudentClassTaskIds.add(teachingClassId);
|
|
|
|
|
return classTasks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void synchronizeClassTaskDefaults(TrainingTask previousTask, TrainingTask updatedTask) {
|
|
|
|
|
if (schoolClassMapper == null || trainingTaskClassConfigMapper == null
|
|
|
|
|
|| previousTask == null || updatedTask == null) {
|
|
|
|
|
|