001    package net.sf.cpsolver.studentsct.model;
002    
003    import java.util.Collections;
004    import java.util.HashSet;
005    import java.util.Set;
006    
007    /**
008     * Representation of a course offering. A course offering contains id, subject
009     * area, course number and an instructional offering. <br>
010     * <br>
011     * Each instructional offering (see {@link Offering}) is offered under one or
012     * more course offerings.
013     * 
014     * <br>
015     * <br>
016     * 
017     * @version StudentSct 1.2 (Student Sectioning)<br>
018     *          Copyright (C) 2007 - 2010 Tomas Muller<br>
019     *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020     *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
021     * <br>
022     *          This library is free software; you can redistribute it and/or modify
023     *          it under the terms of the GNU Lesser General Public License as
024     *          published by the Free Software Foundation; either version 3 of the
025     *          License, or (at your option) any later version. <br>
026     * <br>
027     *          This library is distributed in the hope that it will be useful, but
028     *          WITHOUT ANY WARRANTY; without even the implied warranty of
029     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
030     *          Lesser General Public License for more details. <br>
031     * <br>
032     *          You should have received a copy of the GNU Lesser General Public
033     *          License along with this library; if not see
034     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
035     */
036    public class Course {
037        private long iId = -1;
038        private String iSubjectArea = null;
039        private String iCourseNumber = null;
040        private Offering iOffering = null;
041        private int iLimit = 0, iProjected = 0;
042        private double iEnrollmentWeight = 0.0;
043        private Set<Enrollment> iEnrollments = new HashSet<Enrollment>();
044        private Set<CourseRequest> iRequests = Collections.synchronizedSet(new HashSet<CourseRequest>());
045        private String iNote = null;
046    
047        /**
048         * Constructor
049         * 
050         * @param id
051         *            course offering unique id
052         * @param subjectArea
053         *            subject area (e.g., MA, CS, ENGL)
054         * @param courseNumber
055         *            course number under the given subject area
056         * @param offering
057         *            instructional offering which is offered under this course
058         *            offering
059         */
060        public Course(long id, String subjectArea, String courseNumber, Offering offering) {
061            iId = id;
062            iSubjectArea = subjectArea;
063            iCourseNumber = courseNumber;
064            iOffering = offering;
065            iOffering.getCourses().add(this);
066        }
067    
068        /**
069         * Constructor
070         * 
071         * @param id
072         *            course offering unique id
073         * @param subjectArea
074         *            subject area (e.g., MA, CS, ENGL)
075         * @param courseNumber
076         *            course number under the given subject area
077         * @param offering
078         *            instructional offering which is offered under this course
079         *            offering
080         * @param limit
081         *            course offering limit (-1 for unlimited)
082         * @param projected
083         *            projected demand
084         */
085        public Course(long id, String subjectArea, String courseNumber, Offering offering, int limit, int projected) {
086            iId = id;
087            iSubjectArea = subjectArea;
088            iCourseNumber = courseNumber;
089            iOffering = offering;
090            iOffering.getCourses().add(this);
091            iLimit = limit;
092            iProjected = projected;
093        }
094    
095        /** Course offering unique id */
096        public long getId() {
097            return iId;
098        }
099    
100        /** Subject area */
101        public String getSubjectArea() {
102            return iSubjectArea;
103        }
104    
105        /** Course number */
106        public String getCourseNumber() {
107            return iCourseNumber;
108        }
109    
110        /** Course offering name: subject area + course number */
111        public String getName() {
112            return iSubjectArea + " " + iCourseNumber;
113        }
114    
115        @Override
116        public String toString() {
117            return getName();
118        }
119    
120        /** Instructional offering which is offered under this course offering. */
121        public Offering getOffering() {
122            return iOffering;
123        }
124    
125        /** Course offering limit */
126        public int getLimit() {
127            return iLimit;
128        }
129    
130        /** Set course offering limit */
131        public void setLimit(int limit) {
132            iLimit = limit;
133        }
134    
135        /** Course offering projected number of students */
136        public int getProjected() {
137            return iProjected;
138        }
139        
140        /** Called when an enrollment with this course is assigned to a request */
141        public void assigned(Enrollment enrollment) {
142            iEnrollments.add(enrollment);
143            iEnrollmentWeight += enrollment.getRequest().getWeight();
144        }
145    
146        /** Called when an enrollment with this course is unassigned from a request */
147        public void unassigned(Enrollment enrollment) {
148            iEnrollments.remove(enrollment);
149            iEnrollmentWeight -= enrollment.getRequest().getWeight();
150        }
151        
152        /**
153         * Enrollment weight -- weight of all requests that are enrolled into this course,
154         * excluding the given one. See
155         * {@link Request#getWeight()}.
156         */
157        public double getEnrollmentWeight(Request excludeRequest) {
158            double weight = iEnrollmentWeight;
159            if (excludeRequest != null && excludeRequest.getAssignment() != null
160                    && iEnrollments.contains(excludeRequest.getAssignment()))
161                weight -= excludeRequest.getWeight();
162            return weight;
163        }
164        
165        /** Set of assigned enrollments */
166        public Set<Enrollment> getEnrollments() {
167            return iEnrollments;
168        }
169        
170        /** Set of course requests requesting this course */
171        public Set<CourseRequest> getRequests() {
172            return iRequests;
173        }
174        
175        /**
176         * Course note
177         */
178        public String getNote() { return iNote; }
179        
180        /**
181         * Course note
182         */
183        public void setNote(String note) { iNote = note; }
184    
185        @Override
186        public boolean equals(Object o) {
187            if (o == null || !(o instanceof Course)) return false;
188            return getId() == ((Course)o).getId();
189        }
190        
191        @Override
192        public int hashCode() {
193            return (int) (iId ^ (iId >>> 32));
194        }
195    }