io.github.oliviercailloux.plaquette.Cacher Maven / Gradle / Ivy
package io.github.oliviercailloux.plaquette;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import ebx.ebx_dataservices.StandardException;
import jakarta.xml.bind.JAXBElement;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import schemas.ebx.dataservices_1.CourseType.Root.Course;
import schemas.ebx.dataservices_1.CourseType.Root.Course.Contacts;
import schemas.ebx.dataservices_1.PersonType.Root.Person;
import schemas.ebx.dataservices_1.ProgramType.Root.Program;
public class Cacher {
@SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(Cacher.class);
public static Cacher cache(Querier querier, Set programIds) throws StandardException {
final ImmutableSet.Builder builder = ImmutableSet.builder();
final Set programIdsSeen = new LinkedHashSet<>();
ImmutableSet nextIds = ImmutableSet.copyOf(programIds);
do {
final ImmutableList programs = querier.getPrograms(nextIds);
builder.addAll(programs);
programs.stream().map(p -> p.getProgramID()).forEach(programIdsSeen::add);
LOGGER.debug("Program ids seen: {}.", programIdsSeen);
ImmutableSet subProgramIds = programs.stream()
.flatMap(p -> p.getProgramStructure().getValue().getRefProgram().stream())
.collect(ImmutableSet.toImmutableSet());
nextIds = Sets.difference(subProgramIds, programIds).immutableCopy();
verify(Sets.intersection(nextIds, programIdsSeen).isEmpty());
} while (!nextIds.isEmpty());
final ImmutableSet programs = builder.build();
LOGGER.debug("Programs: {}.",
programs.stream().map(p -> name(p)).collect(Collectors.joining(", ")));
LOGGER.debug("Programs and courses: {}.",
programs.stream().map(p -> name(p) + ": " + p.getProgramStructure().getValue()
.getRefCourse().stream().collect(Collectors.joining(", ")))
.collect(Collectors.joining("; ")));
final ImmutableSet courseIds =
programs.stream().flatMap(p -> p.getProgramStructure().getValue().getRefCourse().stream())
.collect(ImmutableSet.toImmutableSet());
LOGGER.debug("Course ids: {}.", courseIds);
final ImmutableList courses = querier.getCourses(courseIds);
LOGGER.debug("Courses: {}.",
courses.stream()
.map(c -> c.getCourseID() + " - " + c.getCourseName().getValue().getFr().getValue())
.collect(Collectors.joining(", ")));
final ImmutableSet teacherIds = courses.stream()
.flatMap(c -> getTeacherRefs(c).stream()).collect(ImmutableSet.toImmutableSet());
final ImmutableList teachers = querier.getPersons(teacherIds);
return new Cacher(programs, courses, teachers);
}
private static String name(Program p) {
// p.getProgramName() == null ? p.getProgramID():
return p.getProgramName().getValue().getFr().getValue();
}
private static Optional valueOpt(JAXBElement element) {
return element == null ? Optional.empty() : Optional.of(element.getValue());
}
private static List getTeacherRefs(Course course) {
return valueOpt(course.getContacts()).map(Contacts::getRefPerson).orElse(ImmutableList.of());
}
private final ImmutableBiMap programs;
private final ImmutableBiMap courses;
private final ImmutableBiMap teachers;
private Cacher(Set programs, List courses, List teachers) {
this.programs =
programs.stream().collect(ImmutableBiMap.toImmutableBiMap(Program::getProgramID, p -> p));
this.courses =
courses.stream().collect(ImmutableBiMap.toImmutableBiMap(Course::getCourseID, c -> c));
this.teachers =
teachers.stream().collect(ImmutableBiMap.toImmutableBiMap(Person::getPersonID, p -> p));
}
public ImmutableMap getPrograms() {
return programs;
}
public Program getProgram(String programId) {
checkArgument(programs.containsKey(programId));
return programs.get(programId);
}
public ImmutableMap getCourses() {
return courses;
}
public ImmutableMap getProgramCourses(String programId) {
final List courseRefs =
getProgram(programId).getProgramStructure().getValue().getRefCourse();
return ImmutableMap.copyOf(Maps.filterKeys(courses, courseRefs::contains));
}
public Course getCourse(String courseId) {
checkArgument(courses.containsKey(courseId));
return courses.get(courseId);
}
public ImmutableMap getTeachers() {
return teachers;
}
public ImmutableBiMap getCourseTeachers(String courseId) {
final List teacherRefs = getTeacherRefs(getCourse(courseId));
return ImmutableBiMap.copyOf(Maps.filterKeys(teachers, teacherRefs::contains));
}
public Person getTeacher(String teacherId) {
checkArgument(teachers.containsKey(teacherId));
return teachers.get(teacherId);
}
}