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