001package org.cpsolver.studentsct.reservation; 002 003import java.util.Collection; 004import java.util.HashMap; 005import java.util.HashSet; 006import java.util.Map; 007import java.util.Set; 008 009import org.cpsolver.studentsct.model.AreaClassificationMajor; 010import org.cpsolver.studentsct.model.Course; 011import org.cpsolver.studentsct.model.Offering; 012import org.cpsolver.studentsct.model.Student; 013 014/** 015 * Group restriction. Students are matched based on their academic area. 016 * If classifications and/or majors are included, student must match on them as well. 017 * <br> 018 * <br> 019 * 020 * @author Tomáš Müller 021 * @version StudentSct 1.3 (Student Sectioning)<br> 022 * Copyright (C) 2007 - 2020 Tomáš Müller<br> 023 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 024 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 025 * <br> 026 * This library is free software; you can redistribute it and/or modify 027 * it under the terms of the GNU Lesser General Public License as 028 * published by the Free Software Foundation; either version 3 of the 029 * License, or (at your option) any later version. <br> 030 * <br> 031 * This library is distributed in the hope that it will be useful, but 032 * WITHOUT ANY WARRANTY; without even the implied warranty of 033 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 034 * Lesser General Public License for more details. <br> 035 * <br> 036 * You should have received a copy of the GNU Lesser General Public 037 * License along with this library; if not see 038 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 039 */ 040public class CurriculumRestriction extends Restriction { 041 private Set<String> iAcadAreas = new HashSet<String>(); 042 private Set<String> iClassifications = new HashSet<String>(); 043 private Set<String> iMajors = new HashSet<String>(); 044 private Set<String> iMinors = new HashSet<String>(); 045 private Map<String, Set<String>> iConcentrations = null; 046 047 /** 048 * Constructor 049 * @param id restriction unique id 050 * @param offering instructional offering on which the restriction is set 051 * @param acadAreas one or more academic areas 052 * @param classifications zero or more classifications (classifications must match if not empty) 053 * @param majors zero or more majors (majors must match if not empty) 054 * @param minors zero or more majors (minors must match if not empty) 055 */ 056 public CurriculumRestriction(long id, Offering offering, Collection<String> acadAreas, Collection<String> classifications, Collection<String> majors, Collection<String> minors) { 057 super(id, offering); 058 if (acadAreas != null) 059 iAcadAreas.addAll(acadAreas); 060 if (classifications != null) 061 iClassifications.addAll(classifications); 062 if (majors != null) 063 iMajors.addAll(majors); 064 if (minors != null) 065 iMinors.addAll(minors); 066 } 067 068 /** 069 * Constructor 070 * @param id restriction unique id 071 * @param offering instructional offering on which the restriction is set 072 * @param acadAreas one or more academic areas 073 * @param classifications zero or more classifications (classifications must match if not empty) 074 * @param majors zero or more majors (majors must match if not empty) 075 */ 076 public CurriculumRestriction(long id, Offering offering, Collection<String> acadAreas, Collection<String> classifications, Collection<String> majors) { 077 super(id, offering); 078 if (acadAreas != null) 079 iAcadAreas.addAll(acadAreas); 080 if (classifications != null) 081 iClassifications.addAll(classifications); 082 if (majors != null) 083 iMajors.addAll(majors); 084 } 085 086 /** 087 * Constructor 088 * @param id restriction unique id 089 * @param offering instructional offering on which the restriction is set 090 * @param acadArea academic area 091 * @param classifications zero or more classifications (classifications must match if not empty) 092 * @param majors zero or more majors (majors must match if not empty) 093 */ 094 @Deprecated 095 public CurriculumRestriction(long id, Offering offering, String acadArea, Collection<String> classifications, Collection<String> majors) { 096 super(id, offering); 097 iAcadAreas.add(acadArea); 098 if (classifications != null) 099 iClassifications.addAll(classifications); 100 if (majors != null) 101 iMajors.addAll(majors); 102 } 103 104 /** 105 * Academic areas 106 * @return selected academic areas 107 */ 108 public Set<String> getAcademicAreas() { 109 return iAcadAreas; 110 } 111 112 /** 113 * Academic area 114 * @return selected academic area 115 */ 116 @Deprecated 117 public String getAcademicArea() { 118 if (getAcademicAreas().isEmpty()) return ""; 119 return getAcademicAreas().iterator().next(); 120 } 121 122 /** 123 * Majors 124 * @return selected majors 125 */ 126 public Set<String> getMajors() { 127 return iMajors; 128 } 129 130 /** 131 * Minors 132 * @return selected minors 133 */ 134 public Set<String> getMinors() { 135 return iMinors; 136 } 137 138 /** 139 * Academic classifications 140 * @return selected academic classifications 141 */ 142 public Set<String> getClassifications() { 143 return iClassifications; 144 } 145 146 /** Concentrations for major */ 147 public Set<String> getConcentrations(String major) { 148 return (iConcentrations == null ? null : iConcentrations.get(major)); 149 } 150 151 /** Add concentration for major */ 152 public void addConcentration(String major, String concentration) { 153 if (iConcentrations == null) iConcentrations = new HashMap<String, Set<String>>(); 154 Set<String> concentrations = iConcentrations.get(major); 155 if (concentrations == null) { 156 concentrations = new HashSet<String>(); 157 iConcentrations.put(major, concentrations); 158 } 159 concentrations.add(concentration); 160 } 161 162 /** 163 * Check the area, classifications and majors 164 */ 165 @Override 166 public boolean isApplicable(Student student, Course course) { 167 if (!getMajors().isEmpty() || getMinors().isEmpty()) 168 for (AreaClassificationMajor acm: student.getAreaClassificationMajors()) 169 if (getAcademicAreas().contains(acm.getArea()) && 170 (getClassifications().isEmpty() || getClassifications().contains(acm.getClassification())) && 171 (getMajors().isEmpty() || getMajors().contains(acm.getMajor()))) { 172 Set<String> conc = getConcentrations(acm.getMajor()); 173 if (conc != null && !conc.isEmpty()) { 174 return acm.getConcentration() != null && conc.contains(acm.getConcentration()); 175 } else { 176 return true; 177 } 178 } 179 if (!getMinors().isEmpty()) 180 for (AreaClassificationMajor acm: student.getAreaClassificationMinors()) 181 if (getAcademicAreas().contains(acm.getArea()) && 182 (getClassifications().isEmpty() || getClassifications().contains(acm.getClassification())) && 183 (getMinors().contains(acm.getMajor()))) 184 return true; 185 return false; 186 } 187}