001    package net.sf.cpsolver.studentsct.model;
002    
003    import java.util.Enumeration;
004    import java.util.HashSet;
005    import java.util.Vector;
006    
007    /**
008     * Representation of an instructional offering. An offering contains id, name, the list of course offerings, and the list of 
009     * possible configurations. See {@link Config} and {@link Course}.
010     *  
011     * <br><br>
012     * 
013     * @version
014     * StudentSct 1.1 (Student Sectioning)<br>
015     * Copyright (C) 2007 Tomáš Müller<br>
016     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
017     * Lazenska 391, 76314 Zlin, Czech Republic<br>
018     * <br>
019     * This library is free software; you can redistribute it and/or
020     * modify it under the terms of the GNU Lesser General Public
021     * License as published by the Free Software Foundation; either
022     * version 2.1 of the License, or (at your option) any later version.
023     * <br><br>
024     * This library is distributed in the hope that it will be useful,
025     * but WITHOUT ANY WARRANTY; without even the implied warranty of
026     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
027     * Lesser General Public License for more details.
028     * <br><br>
029     * You should have received a copy of the GNU Lesser General Public
030     * License along with this library; if not, write to the Free Software
031     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
032     */
033    public class Offering {
034        private long iId = -1;
035        private String iName = null;
036        private Vector iConfigs = new Vector();
037        private Vector iCourses = new Vector();
038        
039        /** Constructor
040         * @param id instructional offering unique id
041         * @param name instructional offering name (this is usually the name of the controlling course)
042         */
043        public Offering(long id, String name) {
044            iId = id; iName = name;
045        }
046    
047        /** Offering id */
048        public long getId() {
049            return iId;
050        }
051        
052        /** Offering name */
053        public String getName() {
054            return iName;
055        }
056        
057        /** Possible configurations */
058        public Vector getConfigs() {
059            return iConfigs;
060        }
061    
062        /** List of courses. One instructional offering can contain multiple courses (names under which it is offered) */
063        public Vector getCourses() {
064            return iCourses;
065        }
066        
067        /** Return section of the given id, if it is part of one of this offering configurations. */
068        public Section getSection(long sectionId) {
069            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
070                Config config = (Config)e.nextElement();
071                for (Enumeration f=config.getSubparts().elements();f.hasMoreElements();) {
072                    Subpart subpart = (Subpart)f.nextElement();
073                    for (Enumeration g=subpart.getSections().elements();g.hasMoreElements();) {
074                        Section section = (Section)g.nextElement();
075                        if (section.getId()==sectionId)
076                            return section;
077                    }
078                }
079            }
080            return null;
081        }
082        
083        /** Return course, under which the given student enrolls into this offering. */
084        public Course getCourse(Student student) {
085            if (getCourses().size()==0)
086                return null;
087            if (getCourses().size()==1)
088                return (Course)getCourses().firstElement();
089            for (Enumeration e=student.getRequests().elements();e.hasMoreElements();) {
090                Request request = (Request)e.nextElement();
091                if (request instanceof CourseRequest) {
092                    for (Enumeration f=((CourseRequest)request).getCourses().elements();f.hasMoreElements();) {
093                        Course course = (Course)f.nextElement();
094                        if (getCourses().contains(course)) return course;
095                    }
096                }
097            }
098            return (Course)getCourses().firstElement();
099        }
100        
101        /** Return set of instructional types, union over all configurations. */
102        public HashSet getInstructionalTypes() {
103            HashSet instructionalTypes = new HashSet();
104            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
105                Config config = (Config)e.nextElement();
106                for (Enumeration f=config.getSubparts().elements();f.hasMoreElements();) {
107                    Subpart subpart = (Subpart)f.nextElement();
108                    instructionalTypes.add(subpart.getInstructionalType());
109                }
110            }
111            return instructionalTypes;
112        }
113        
114        /** Return the list of all possible choices of the given instructional type for this offering. */
115        public HashSet getChoices(String instructionalType) {
116            HashSet choices = new HashSet();
117            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
118                Config config = (Config)e.nextElement();
119                for (Enumeration f=config.getSubparts().elements();f.hasMoreElements();) {
120                    Subpart subpart = (Subpart)f.nextElement();
121                    if (!instructionalType.equals(subpart.getInstructionalType())) continue;
122                    choices.addAll(subpart.getChoices());
123                }
124            }
125            return choices;
126        }
127        
128        /** Return list of all subparts of the given isntructional type for this offering. */
129        public HashSet getSubparts(String instructionalType) {
130            HashSet subparts = new HashSet();
131            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
132                Config config = (Config)e.nextElement();
133                for (Enumeration f=config.getSubparts().elements();f.hasMoreElements();) {
134                    Subpart subpart = (Subpart)f.nextElement();
135                    if (instructionalType.equals(subpart.getInstructionalType())) 
136                        subparts.add(subpart);
137                }
138            }
139            return subparts;
140        }
141        
142        /** Minimal penalty from {@link Config#getMinPenalty()} */
143        public double getMinPenalty() {
144            double min = Double.MAX_VALUE;
145            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
146                Config config = (Config)e.nextElement();
147                min = Math.min(min, config.getMinPenalty());
148            }
149            return (min==Double.MAX_VALUE?0.0:min);
150        }
151        
152        /** Maximal penalty from {@link Config#getMaxPenalty()} */
153        public double getMaxPenalty() {
154            double max = Double.MIN_VALUE;
155            for (Enumeration e=getConfigs().elements();e.hasMoreElements();) {
156                Config config = (Config)e.nextElement();
157                max = Math.max(max, config.getMaxPenalty());
158            }
159            return (max==Double.MIN_VALUE?0.0:max);
160        }
161        
162        public String toString() {
163            return iName;
164        }
165        
166    }