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