Skip to main content
Rollback to Revision 3
Source Link
toolic
  • 15.9k
  • 6
  • 29
  • 217

Edit: Updated to account for "Sharon Ben Asher"'s suggestions

package com.exercise.mathplan;

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBException;

public class MathplanApplication {
    
    static final String TIMETABLE_URL = "./src/main/resources/timetable.xml";
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for room '%s' 
        on %s %n""";
    
    private static String CURRICULARCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for curriculum '%s'
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        List<ClassBooking> cbList = 
                UniversityFileParser.parseUniversityFile(TIMETABLE_URL);
        
        resultPresentation(new ScheduleConflictDiscovery().findSchedulingConflicts(cbList));
    }

    
    private static void resultPresentation(Map<String, Set<List<ClassBooking>>> conflictMap) {
        
        if (!conflictMap.get("room").isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                conflictMap.get("room").size());
        }
        
        conflictMap.get("room").forEach(st -> printRoomConflict(st));
        
        if (!conflictMap.get("curricular").isEmpty()) {
            System.out.printf("%nThere were %d curricular conflicts discovered: %n", 
                conflictMap.get("curricular").size());
        }
        
        conflictMap.get("curricular").forEach(st -> printCurricularConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static void printCurricularConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(CURRICULARCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.JAXBException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for room %s 
        on %s %n""";
    
    private static String PROGRAMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for program %s
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        SpringApplication.run(Application.class, args);
        
            
        List<ClassBooking> cbList = 
            UniversityFileParser.parseUniversityFile(
            "./src/main/resources/timetable.xml");
            
        ScheduleConflictDiscovery.findSchedulingConflicts(cbList);
            
        resultPresentation();
    }

    
    private static void resultPresentation() {
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                ScheduleConflictDiscovery.getRoomConflicts().size());
        }
        
        ScheduleConflictDiscovery.getRoomConflicts().forEach(
            st -> printRoomConflict(st));
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("%nThere were %d program conflicts discovered: %n", 
                ScheduleConflictDiscovery.getProgramConflicts().size());
        }
        
        ScheduleConflictDiscovery.getProgramConflicts().forEach(
            st -> printProgramConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString());
    }
    
    
    private static void printProgramConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(PROGRAMCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}

@Component
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    private static Map<String,List<String>> curriculumMap = new HashMap<>();
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    private UniversityFileParser() throws JAXBException {
        jaxbContext = JAXBContext.newInstance(University.class);
    }
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                getJaxbContext()jaxbContext.createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        return parseLecturesparseCurriculum(university);
    }
    
    private static JAXBContext getJaxbContext() throws JAXBExceptionreturn {parseLectures(university);
        }
        if(jaxbContext == null) {
        
    private jaxbContextstatic =void JAXBContext.newInstanceparseCurriculum(University.class);
       university) }{
        
        return jaxbContext;
    }
 for (Curriculum curr: university.getCurricula().getCurriculum()){
    
     private static Map<String, List<String>> parseCurriculum(University university) {
        
      List<Lecture> newCurriculum Map<String,List<String>>=
 curriculumMap = new HashMap<>();
        
         universitycurr.getCurriculagetLecture().getCurriculumstream().forEachmap(
            currentry -> curriculumMap.put(currLecture) entry.getNamegetValue(), )
                    buildStringPresentationOfCurriculum.toList(curr)));
        
        return curriculumMap;
    }
    
     privateList<String> staticnewCurriculumString List<String>= buildStringPresentationOfCurriculumnewCurriculum.stream(Curriculum curr) { .
  
         
         List<Lecture> newCurriculum =map(Lecture::getId).toList();
            curr.getLecture()curriculumMap.streamput()curr.map(entry -> getName(Lecture), entry.getValue()).toList(newCurriculumString);
        
        return newCurriculum.stream().
            map(Lecture::getId).toList();}
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        Map<String, List<String>> curriculumMap = parseCurriculum(university);
        
        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                    lecture.getRoombookings(), curriculumMap)).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings, Map<String, List<String>> curriculumMap) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            classBookings.add(ClassBooking cb = new ClassBooking(id, b.getRoom(),
                    getWeekday(b.getWeekday()),
                    LocalTime.of(b.getStartTime().getHour(), 0),
                    LocalTime.of(b.getEndTime().getHour(), 0),
                addPrograms(id));
          addCurriculum(id, curriculumMap)) 
            classBookings.add(cb);
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addCurriculumaddPrograms(String courseID,) {
        
        Map<String,Set<String> List<String>>programSet curriculumMap)= {new HashSet<>();
        
        returnfor (Entry<String, List<String>> degree: curriculumMap.entrySet().stream()
  {
           .filter(degree ->if (degree.getValue().contains(courseID)).map(Entry::getKey) {
                
                programSet.collectadd(Collectorsdegree.toSetgetKey());
            }
        }
        
        return programSet;
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
} 

    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> curricularConflicts;
programConflicts;
    
    public Map<String,static Set<List<ClassBooking>>>void findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        curricularConflictsprogramConflicts = new HashSet<>();
        
        findOverlaps(cbList);
        
        Map<String, Set<List<ClassBooking>>> resultMap = new HashMap<>();
        resultMap.put("room", roomConflicts);
        resultMap.put("curricular", curricularConflicts);
        
        return Map.ofEntries(
            Map.entry("room", roomConflicts), Map.entry("curricular", curricularConflicts));
    }
    
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
        }    
        }
    }
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                curricularConflictsprogramConflicts.add(cbSet);
            }
        }
    }
    
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }

    public static Set<List<ClassBooking>> getRoomConflicts() {
        return roomConflicts;
    }

    public static Set<List<ClassBooking>> getProgramConflicts() {
        return programConflicts;
    }
}

Edit: Updated to account for "Sharon Ben Asher"'s suggestions

package com.exercise.mathplan;

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBException;

public class MathplanApplication {
    
    static final String TIMETABLE_URL = "./src/main/resources/timetable.xml";
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for room '%s' 
        on %s %n""";
    
    private static String CURRICULARCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for curriculum '%s'
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        List<ClassBooking> cbList = 
                UniversityFileParser.parseUniversityFile(TIMETABLE_URL);
        
        resultPresentation(new ScheduleConflictDiscovery().findSchedulingConflicts(cbList));
    }

    
    private static void resultPresentation(Map<String, Set<List<ClassBooking>>> conflictMap) {
        
        if (!conflictMap.get("room").isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                conflictMap.get("room").size());
        }
        
        conflictMap.get("room").forEach(st -> printRoomConflict(st));
        
        if (!conflictMap.get("curricular").isEmpty()) {
            System.out.printf("%nThere were %d curricular conflicts discovered: %n", 
                conflictMap.get("curricular").size());
        }
        
        conflictMap.get("curricular").forEach(st -> printCurricularConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static void printCurricularConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(CURRICULARCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                getJaxbContext().createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        return parseLectures(university);
    }
    
    private static JAXBContext getJaxbContext() throws JAXBException {
        
        if(jaxbContext == null) {
            jaxbContext = JAXBContext.newInstance(University.class);
        }
        
        return jaxbContext;
    }
    
    
     private static Map<String, List<String>> parseCurriculum(University university) {
        
        Map<String,List<String>> curriculumMap = new HashMap<>();
        
         university.getCurricula().getCurriculum().forEach(
            curr -> curriculumMap.put(curr.getName(), 
                    buildStringPresentationOfCurriculum(curr)));
        
        return curriculumMap;
    }
    
     private static List<String> buildStringPresentationOfCurriculum(Curriculum curr) {   
         
         List<Lecture> newCurriculum =
            curr.getLecture().stream().map(entry -> (Lecture) entry.getValue()).toList();
        
        return newCurriculum.stream().
            map(Lecture::getId).toList();
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        Map<String, List<String>> curriculumMap = parseCurriculum(university);
        
        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                lecture.getRoombookings(), curriculumMap)).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings, Map<String, List<String>> curriculumMap) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            classBookings.add(new ClassBooking(id, b.getRoom(),
                    getWeekday(b.getWeekday()),
                    LocalTime.of(b.getStartTime().getHour(), 0),
                    LocalTime.of(b.getEndTime().getHour(), 0),
                    addCurriculum(id, curriculumMap)));
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addCurriculum(String courseID, 
        Map<String, List<String>> curriculumMap) {
        
        return curriculumMap.entrySet().stream()
             .filter(degree -> degree.getValue().contains(courseID)).map(Entry::getKey)
            .collect(Collectors.toSet());
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
}
    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> curricularConflicts;

    
    public Map<String, Set<List<ClassBooking>>> findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        curricularConflicts = new HashSet<>();
        
        findOverlaps(cbList);
        
        Map<String, Set<List<ClassBooking>>> resultMap = new HashMap<>();
        resultMap.put("room", roomConflicts);
        resultMap.put("curricular", curricularConflicts);
        
        return Map.ofEntries(
            Map.entry("room", roomConflicts), Map.entry("curricular", curricularConflicts));
    }
    
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
        }
    }
    
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                curricularConflicts.add(cbSet);
            }
        }
    }
    
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }
}

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.JAXBException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for room %s 
        on %s %n""";
    
    private static String PROGRAMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for program %s
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        SpringApplication.run(Application.class, args);
        
            
        List<ClassBooking> cbList = 
            UniversityFileParser.parseUniversityFile(
            "./src/main/resources/timetable.xml");
            
        ScheduleConflictDiscovery.findSchedulingConflicts(cbList);
            
        resultPresentation();
    }

    
    private static void resultPresentation() {
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                ScheduleConflictDiscovery.getRoomConflicts().size());
        }
        
        ScheduleConflictDiscovery.getRoomConflicts().forEach(
            st -> printRoomConflict(st));
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("%nThere were %d program conflicts discovered: %n", 
                ScheduleConflictDiscovery.getProgramConflicts().size());
        }
        
        ScheduleConflictDiscovery.getProgramConflicts().forEach(
            st -> printProgramConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString());
    }
    
    
    private static void printProgramConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(PROGRAMCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}

@Component
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    private static Map<String,List<String>> curriculumMap = new HashMap<>();
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    private UniversityFileParser() throws JAXBException {
        jaxbContext = JAXBContext.newInstance(University.class);
    }
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                jaxbContext.createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        parseCurriculum(university);
        
        return parseLectures(university);
    }
    
     
    private static void parseCurriculum(University university) {
        
        for (Curriculum curr: university.getCurricula().getCurriculum()){
            
            List<Lecture> newCurriculum =
                    curr.getLecture().stream().map(entry -> (Lecture) entry.getValue())
                    .toList();
            
            List<String> newCurriculumString = newCurriculum.stream().
                    map(Lecture::getId).toList();
            curriculumMap.put(curr.getName(), newCurriculumString);
            
        }
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                    lecture.getRoombookings())).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            ClassBooking cb = new ClassBooking(id,b.getRoom(),
                getWeekday(b.getWeekday()),
                LocalTime.of(b.getStartTime().getHour(), 0),
                LocalTime.of(b.getEndTime().getHour(), 0),
                addPrograms(id));
            
            classBookings.add(cb);
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addPrograms(String courseID) {
        
        Set<String> programSet = new HashSet<>();
        
        for (Entry<String, List<String>> degree: curriculumMap.entrySet()) {
            if (degree.getValue().contains(courseID)) {
                
                programSet.add(degree.getKey());
            }
        }
        
        return programSet;
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
} 

    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> programConflicts;

    public static void findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        programConflicts = new HashSet<>();
        
        findOverlaps(cbList);
    }
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
            
        }
    }
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                programConflicts.add(cbSet);
            }
        }
    }
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }

    public static Set<List<ClassBooking>> getRoomConflicts() {
        return roomConflicts;
    }

    public static Set<List<ClassBooking>> getProgramConflicts() {
        return programConflicts;
    }
}
added 219 characters in body
Source Link

Edit: Updated to account for "Sharon Ben Asher"'s suggestions


import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.JAXBException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for room %s 
        on %s %n""";
    
    private static String PROGRAMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for program %s
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        SpringApplication.run(Application.class, args);
        
            
        List<ClassBooking> cbList = 
            UniversityFileParser.parseUniversityFile(
            "./src/main/resources/timetable.xml");
            
        ScheduleConflictDiscovery.findSchedulingConflicts(cbList);
            
        resultPresentation();
    }

    
    private static void resultPresentation() {
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                ScheduleConflictDiscovery.getRoomConflicts().size());
        }
        
        ScheduleConflictDiscovery.getRoomConflicts().forEach(
            st -> printRoomConflict(st));
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("%nThere were %d program conflicts discovered: %n", 
                ScheduleConflictDiscovery.getProgramConflicts().size());
        }
        
        ScheduleConflictDiscovery.getProgramConflicts().forEach(
            st -> printProgramConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString());
    }
    
    
    private static void printProgramConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(PROGRAMCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}
package com.exercise.mathplan;

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBException;

public class MathplanApplication {
    
    static final String TIMETABLE_URL = "./src/main/resources/timetable.xml";
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for room '%s' 
        on %s %n""";
    
    private static String CURRICULARCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for curriculum '%s'
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        List<ClassBooking> cbList = 
                UniversityFileParser.parseUniversityFile(TIMETABLE_URL);
        
        resultPresentation(new ScheduleConflictDiscovery().findSchedulingConflicts(cbList));
    }

    
    private static void resultPresentation(Map<String, Set<List<ClassBooking>>> conflictMap) {
        
        if (!conflictMap.get("room").isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                conflictMap.get("room").size());
        }
        
        conflictMap.get("room").forEach(st -> printRoomConflict(st));
        
        if (!conflictMap.get("curricular").isEmpty()) {
            System.out.printf("%nThere were %d curricular conflicts discovered: %n", 
                conflictMap.get("curricular").size());
        }
        
        conflictMap.get("curricular").forEach(st -> printCurricularConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static void printCurricularConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(CURRICULARCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}

@Component
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    private static Map<String,List<String>> curriculumMap = new HashMap<>();
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    private UniversityFileParser() throws JAXBException {
        jaxbContext = JAXBContext.newInstance(University.class);
    }
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                jaxbContextgetJaxbContext().createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        parseCurriculumreturn parseLectures(university);
    }
    
      private static returnJAXBContext parseLecturesgetJaxbContext(university);
  throws JAXBException }{
    
     
    private static void parseCurriculum if(UniversityjaxbContext university== null) {
            jaxbContext = JAXBContext.newInstance(University.class);
        for}
 (Curriculum curr: university.getCurricula().getCurriculum()){     
        return jaxbContext;
    }
     
     
    List<Lecture>private newCurriculumstatic =Map<String, List<String>> parseCurriculum(University university) {
        
        Map<String,List<String>> curriculumMap = new HashMap<>();
        curr
        university.getLecturegetCurricula().streamgetCurriculum().mapforEach(entry
            curr -> curriculumMap.put(Lecture) entrycurr.getValuegetName()), 
                    .toListbuildStringPresentationOfCurriculum(curr)));
        
        return curriculumMap;
    }
     
    List<String>private newCurriculumStringstatic =List<String> newCurriculum.streambuildStringPresentationOfCurriculum(Curriculum curr).
 {    
         
        map(Lecture::getId).toList();List<Lecture> newCurriculum =
            curriculumMapcurr.putgetLecture(curr).getNamestream(),.map(entry newCurriculumString-> (Lecture) entry.getValue()).toList();
        
        return newCurriculum.stream().
        }    map(Lecture::getId).toList();
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        Map<String, List<String>> curriculumMap = parseCurriculum(university);
        
        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                    lecture.getRoombookings(), curriculumMap)).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings, Map<String, List<String>> curriculumMap) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            ClassBooking cb = classBookings.add(new ClassBooking(id, b.getRoom(),
                    getWeekday(b.getWeekday()),
                    LocalTime.of(b.getStartTime().getHour(), 0),
                    LocalTime.of(b.getEndTime().getHour(), 0),
                addPrograms(id));
            
            classBookings.addaddCurriculum(cbid, curriculumMap)));
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addProgramsaddCurriculum(String courseID) {
       , 
        Set<String> programSet =Map<String, newList<String>> HashSet<>(curriculumMap); {
        
        for (Entry<String, List<String>> degree:return curriculumMap.entrySet().stream() {
            if .filter(degree -> degree.getValue().contains(courseID)) {
                .map(Entry::getKey)
                programSet.addcollect(degreeCollectors.getKeytoSet());
            }
        }
        
        return programSet;
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
}
 
    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> programConflicts;curricularConflicts;

    
    public staticMap<String, voidSet<List<ClassBooking>>> findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        programConflictscurricularConflicts = new HashSet<>();
        
        findOverlaps(cbList);
        
        Map<String, Set<List<ClassBooking>>> resultMap = new HashMap<>();
        resultMap.put("room", roomConflicts);
        resultMap.put("curricular", curricularConflicts);
        
        return Map.ofEntries(
            Map.entry("room", roomConflicts), Map.entry("curricular", curricularConflicts));
    }
    
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
            }
        }
    }
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                programConflictscurricularConflicts.add(cbSet);
            }
        }
    }
    
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }

    public static Set<List<ClassBooking>> getRoomConflicts() {
        return roomConflicts;
    }

    public static Set<List<ClassBooking>> getProgramConflicts() {
        return programConflicts;
    }
}

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.xml.bind.JAXBException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for room %s 
        on %s %n""";
    
    private static String PROGRAMCONFLICT_MSG = """
        Course with ID %s and course with ID %s have a scheduling conflict for program %s
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        SpringApplication.run(Application.class, args);
        
            
        List<ClassBooking> cbList = 
            UniversityFileParser.parseUniversityFile(
            "./src/main/resources/timetable.xml");
            
        ScheduleConflictDiscovery.findSchedulingConflicts(cbList);
            
        resultPresentation();
    }

    
    private static void resultPresentation() {
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                ScheduleConflictDiscovery.getRoomConflicts().size());
        }
        
        ScheduleConflictDiscovery.getRoomConflicts().forEach(
            st -> printRoomConflict(st));
        
        if (!ScheduleConflictDiscovery.getRoomConflicts().isEmpty()) {
            System.out.printf("%nThere were %d program conflicts discovered: %n", 
                ScheduleConflictDiscovery.getProgramConflicts().size());
        }
        
        ScheduleConflictDiscovery.getProgramConflicts().forEach(
            st -> printProgramConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString());
    }
    
    
    private static void printProgramConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(PROGRAMCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}

@Component
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    private static Map<String,List<String>> curriculumMap = new HashMap<>();
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    private UniversityFileParser() throws JAXBException {
        jaxbContext = JAXBContext.newInstance(University.class);
    }
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                jaxbContext.createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        parseCurriculum(university);
        
        return parseLectures(university);
    }
    
     
    private static void parseCurriculum(University university) {
        
        for (Curriculum curr: university.getCurricula().getCurriculum()){
            
            List<Lecture> newCurriculum =
                    curr.getLecture().stream().map(entry -> (Lecture) entry.getValue())
                    .toList();
            
            List<String> newCurriculumString = newCurriculum.stream().
                    map(Lecture::getId).toList();
            curriculumMap.put(curr.getName(), newCurriculumString);
            
        }
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                    lecture.getRoombookings())).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            ClassBooking cb = new ClassBooking(id,b.getRoom(),
                getWeekday(b.getWeekday()),
                LocalTime.of(b.getStartTime().getHour(), 0),
                LocalTime.of(b.getEndTime().getHour(), 0),
                addPrograms(id));
            
            classBookings.add(cb);
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addPrograms(String courseID) {
        
        Set<String> programSet = new HashSet<>();
        
        for (Entry<String, List<String>> degree: curriculumMap.entrySet()) {
            if (degree.getValue().contains(courseID)) {
                
                programSet.add(degree.getKey());
            }
        }
        
        return programSet;
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
}
 
    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> programConflicts;

    public static void findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        programConflicts = new HashSet<>();
        
        findOverlaps(cbList);
    }
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
            
        }
    }
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                programConflicts.add(cbSet);
            }
        }
    }
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }

    public static Set<List<ClassBooking>> getRoomConflicts() {
        return roomConflicts;
    }

    public static Set<List<ClassBooking>> getProgramConflicts() {
        return programConflicts;
    }
}

Edit: Updated to account for "Sharon Ben Asher"'s suggestions

package com.exercise.mathplan;

import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.JAXBException;

public class MathplanApplication {
    
    static final String TIMETABLE_URL = "./src/main/resources/timetable.xml";
    
    private static String ROOMCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for room '%s' 
        on %s %n""";
    
    private static String CURRICULARCONFLICT_MSG = """
        Course with ID '%s' and course with ID '%s' have a scheduling conflict for curriculum '%s'
        on %s %n""";
    
    
    public static void main(String[] args) throws FileNotFoundException, JAXBException {
        
        List<ClassBooking> cbList = 
                UniversityFileParser.parseUniversityFile(TIMETABLE_URL);
        
        resultPresentation(new ScheduleConflictDiscovery().findSchedulingConflicts(cbList));
    }

    
    private static void resultPresentation(Map<String, Set<List<ClassBooking>>> conflictMap) {
        
        if (!conflictMap.get("room").isEmpty()) {
            System.out.printf("There were %d room conflicts discovered: %n", 
                conflictMap.get("room").size());
        }
        
        conflictMap.get("room").forEach(st -> printRoomConflict(st));
        
        if (!conflictMap.get("curricular").isEmpty()) {
            System.out.printf("%nThere were %d curricular conflicts discovered: %n", 
                conflictMap.get("curricular").size());
        }
        
        conflictMap.get("curricular").forEach(st -> printCurricularConflict(st));
    }

    
    private static void printRoomConflict(List<ClassBooking> cbList) {
        
        System.out.printf(ROOMCONFLICT_MSG, cbList.get(0).getId(), cbList.get(1).getId(),
            cbList.get(0).getRoom(), cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static void printCurricularConflict(List<ClassBooking> cbList) {
        
        String conflictingMajor = getConflictingMajor(cbList.get(0), cbList.get(1));
        
        System.out.printf(CURRICULARCONFLICT_MSG, cbList.get(0).getId(), 
            cbList.get(1).getId(), conflictingMajor, 
            cbList.get(0).getWeekday().toString().toLowerCase());
    }
    
    
    private static String getConflictingMajor(ClassBooking cb1, ClassBooking cb2) {
        
        Set<String> copyCurriculum1 = new HashSet<>(cb1.getInCurriculum());
        copyCurriculum1.retainAll(cb2.getInCurriculum());
        return copyCurriculum1.stream().findFirst().get();
    }
}
public class UniversityFileParser {

    private static JAXBContext jaxbContext;
    static final DateTimeFormatter WEEKDAYFORMATTER = DateTimeFormatter.ofPattern("E", Locale.US);
    
    
    public static List<ClassBooking> parseUniversityFile(String fileURL) 
        throws FileNotFoundException, JAXBException {
        
        University university = (University) JAXBIntrospector.getValue(
                getJaxbContext().createUnmarshaller().unmarshal(new FileReader(fileURL)));
        
        return parseLectures(university);
    }
    
    private static JAXBContext getJaxbContext() throws JAXBException {
        
        if(jaxbContext == null) {
            jaxbContext = JAXBContext.newInstance(University.class);
        }
        
        return jaxbContext;
    }
     
     
    private static Map<String, List<String>> parseCurriculum(University university) {
        
        Map<String,List<String>> curriculumMap = new HashMap<>();
        
        university.getCurricula().getCurriculum().forEach(
            curr -> curriculumMap.put(curr.getName(), 
                    buildStringPresentationOfCurriculum(curr)));
        
        return curriculumMap;
    }
     
    private static List<String> buildStringPresentationOfCurriculum(Curriculum curr) {    
         
        List<Lecture> newCurriculum =
            curr.getLecture().stream().map(entry -> (Lecture) entry.getValue()).toList();
        
        return newCurriculum.stream().
            map(Lecture::getId).toList();
    }
    

    private static List<ClassBooking> parseLectures(University university) {

        Map<String, List<String>> curriculumMap = parseCurriculum(university);
        
        List<List<ClassBooking>> cbList = university.getLectures().getLecture()
            .stream().map(lecture -> parseBookings(lecture.getId(), 
                lecture.getRoombookings(), curriculumMap)).toList();
        
        return cbList.stream().flatMap(Collection::stream).toList();
    }
    
    
    private static List<ClassBooking> parseBookings(String id, 
            Roombookings roomBookings, Map<String, List<String>> curriculumMap) {
        
        List<ClassBooking> classBookings = new ArrayList<>();
        
        for (Booking b: roomBookings.getBooking()) {
            
            classBookings.add(new ClassBooking(id, b.getRoom(),
                    getWeekday(b.getWeekday()),
                    LocalTime.of(b.getStartTime().getHour(), 0),
                    LocalTime.of(b.getEndTime().getHour(), 0),
                    addCurriculum(id, curriculumMap)));
        }
        
        return classBookings;
    }
    
    
    private static Set<String> addCurriculum(String courseID, 
        Map<String, List<String>> curriculumMap) {
        
        return curriculumMap.entrySet().stream()
            .filter(degree -> degree.getValue().contains(courseID)).map(Entry::getKey)
            .collect(Collectors.toSet());
    }
    

    private static DayOfWeek getWeekday(String weekday) {
        
        if ("Thur".equals(weekday)) {
            
            return DayOfWeek.THURSDAY;
        }
        
        return DayOfWeek.from(WEEKDAYFORMATTER.parse(weekday));
    }
}
    
    private static Set<List<ClassBooking>> roomConflicts;
    private static Set<List<ClassBooking>> curricularConflicts;

    
    public Map<String, Set<List<ClassBooking>>> findSchedulingConflicts(List<ClassBooking> cbList) {
        
        roomConflicts = new HashSet<>();
        curricularConflicts = new HashSet<>();
        
        findOverlaps(cbList);
        
        Map<String, Set<List<ClassBooking>>> resultMap = new HashMap<>();
        resultMap.put("room", roomConflicts);
        resultMap.put("curricular", curricularConflicts);
        
        return Map.ofEntries(
            Map.entry("room", roomConflicts), Map.entry("curricular", curricularConflicts));
    }
    
    
    private static void findOverlaps(List<ClassBooking> cbList) {
        
        for (int i = 0;i<cbList.size();i++) {
            
            ClassBooking currCB = cbList.get(i);
            
            List<ClassBooking> overlaps = IntStream.range(i + 1, cbList.size())
                    .filter(j -> hasOverLap(currCB, cbList.get(j)))
                    .mapToObj(cbList::get).toList();
            
            findConflicts(currCB, overlaps);
        }
    }
    
    
    private static void findConflicts(ClassBooking currentCB, 
            List<ClassBooking> overlaps) {
        
        for (ClassBooking cb: overlaps) {
            
            if (currentCB.getRoom().equals(cb.getRoom())) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                roomConflicts.add(cbSet);
            }
            
            Set<String> currMajors = new HashSet<>(currentCB.getInCurriculum());
            currMajors.retainAll(cb.getInCurriculum());
            
            if (!currMajors.isEmpty()) {
                List<ClassBooking> cbSet = List.of(currentCB, cb);
                curricularConflicts.add(cbSet);
            }
        }
    }
    
    
    private static boolean hasOverLap(ClassBooking cb1, ClassBooking cb2) {
        
        return (cb1.getWeekday() == cb2.getWeekday()) &&
            (((cb1.getBeginTime().isBefore(cb2.getBeginTime()) || 
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getEndTime().isAfter(cb2.getBeginTime())) || 
            ((cb1.getBeginTime().isAfter(cb2.getBeginTime()) ||
            cb1.getBeginTime().equals(cb2.getBeginTime())) && 
            cb1.getBeginTime().isBefore(cb2.getEndTime())));
    }
}
deleted 13 characters in body
Source Link
toolic
  • 15.9k
  • 6
  • 29
  • 217

Thank you

Thank you

added 318 characters in body
Source Link
Loading
Source Link
Loading