001package org.cpsolver.studentsct.reservation; 002 003import java.util.Collection; 004import java.util.HashSet; 005import java.util.Set; 006 007import org.cpsolver.studentsct.model.AcademicAreaCode; 008import org.cpsolver.studentsct.model.AreaClassificationMajor; 009import org.cpsolver.studentsct.model.Offering; 010import org.cpsolver.studentsct.model.Student; 011 012 013/** 014 * Curriculum reservation. Students are matched based on their academic area. 015 * If classifications and/or majors are included, student must match on them as well. 016 * 017 * <br> 018 * <br> 019 * 020 * @version StudentSct 1.3 (Student Sectioning)<br> 021 * Copyright (C) 2007 - 2014 Tomas Muller<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 CurriculumReservation extends Reservation { 040 private double iLimit; 041 private String iAcadArea; 042 private Set<String> iClassifications = new HashSet<String>(); 043 private Set<String> iMajors = new HashSet<String>(); 044 045 /** 046 * Reservation priority (lower than individual and group reservations) 047 */ 048 public static final int DEFAULT_PRIORITY = 500; 049 /** 050 * Curriculum reservation does not need to be used 051 */ 052 public static final boolean DEFAULT_MUST_BE_USED = false; 053 /** 054 * Curriculum reservations can not assign over the limit. 055 */ 056 public static final boolean DEFAULT_CAN_ASSIGN_OVER_LIMIT = false; 057 /** 058 * Overlaps are not allowed for curriculum reservations. 059 */ 060 public static final boolean DEFAULT_ALLOW_OVERLAP = false; 061 062 /** 063 * Constructor 064 * @param id unique id 065 * @param limit reservation limit (-1 for unlimited) 066 * @param offering instructional offering on which the reservation is set 067 * @param acadArea academic area 068 * @param classifications zero or more classifications (classifications must match if not empty) 069 * @param majors zero or more majors (majors must match if not empty) 070 */ 071 public CurriculumReservation(long id, double limit, Offering offering, String acadArea, Collection<String> classifications, Collection<String> majors) { 072 super(id, offering, DEFAULT_PRIORITY, DEFAULT_MUST_BE_USED, DEFAULT_CAN_ASSIGN_OVER_LIMIT, DEFAULT_ALLOW_OVERLAP); 073 iLimit = limit; 074 iAcadArea = acadArea; 075 if (classifications != null) 076 iClassifications.addAll(classifications); 077 if (majors != null) 078 iMajors.addAll(majors); 079 } 080 081 /** 082 * Reservation limit (-1 for unlimited) 083 */ 084 @Override 085 public double getReservationLimit() { 086 return iLimit; 087 } 088 089 /** 090 * Set reservation limit (-1 for unlimited) 091 * @param limit reservation limit, -1 for unlimited 092 */ 093 public void setReservationLimit(double limit) { 094 iLimit = limit; 095 } 096 097 098 /** 099 * Academic area 100 * @return selected academic area 101 */ 102 public String getAcademicArea() { 103 return iAcadArea; 104 } 105 106 /** 107 * Majors 108 * @return selected majors 109 */ 110 public Set<String> getMajors() { 111 return iMajors; 112 } 113 114 /** 115 * Academic classifications 116 * @return selected academic classifications 117 */ 118 public Set<String> getClassifications() { 119 return iClassifications; 120 } 121 122 /** 123 * Check the area, classifications and majors 124 */ 125 @Override 126 public boolean isApplicable(Student student) { 127 boolean match = false; 128 for (AreaClassificationMajor acm: student.getAreaClassificationMajors()) 129 if (getAcademicArea().equals(acm.getArea()) && 130 (getClassifications().isEmpty() || getClassifications().contains(acm.getClassification())) && 131 (getMajors().isEmpty() || getMajors().contains(acm.getMajor()))) 132 return true; 133 if (student.getAcademicAreaClasiffications() == null) return false; 134 for (AcademicAreaCode aac: student.getAcademicAreaClasiffications()) { 135 if (getAcademicArea().equals(aac.getArea())) { 136 if (getClassifications().isEmpty() || getClassifications().contains(aac.getCode())) { 137 match = true; break; 138 } 139 } 140 } 141 if (!match) return false; 142 for (AcademicAreaCode aac: student.getMajors()) { 143 if (getAcademicArea().equals(aac.getArea())) { 144 if (getMajors().isEmpty() || getMajors().contains(aac.getCode())) 145 return true; 146 } 147 } 148 return getMajors().isEmpty(); 149 } 150 151 152}