001    package net.sf.cpsolver.studentsct.check;
002    
003    import java.text.DecimalFormat;
004    import java.util.Enumeration;
005    
006    import net.sf.cpsolver.studentsct.StudentSectioningModel;
007    import net.sf.cpsolver.studentsct.model.Config;
008    import net.sf.cpsolver.studentsct.model.Offering;
009    import net.sf.cpsolver.studentsct.model.Section;
010    import net.sf.cpsolver.studentsct.model.Subpart;
011    
012    /**
013     * This class looks and reports cases when a section limit is exceeded.  
014     *  
015     * <br><br>
016     * 
017     * Usage: if (new SectionLimitCheck(model).check()) ...
018     * 
019     * <br><br>
020     * 
021     * @version
022     * StudentSct 1.1 (Student Sectioning)<br>
023     * Copyright (C) 2007 Tomáš Müller<br>
024     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
025     * Lazenska 391, 76314 Zlin, Czech Republic<br>
026     * <br>
027     * This library is free software; you can redistribute it and/or
028     * modify it under the terms of the GNU Lesser General Public
029     * License as published by the Free Software Foundation; either
030     * version 2.1 of the License, or (at your option) any later version.
031     * <br><br>
032     * This library is distributed in the hope that it will be useful,
033     * but WITHOUT ANY WARRANTY; without even the implied warranty of
034     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
035     * Lesser General Public License for more details.
036     * <br><br>
037     * You should have received a copy of the GNU Lesser General Public
038     * License along with this library; if not, write to the Free Software
039     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
040     */
041    public class SectionLimitCheck {
042        private static org.apache.log4j.Logger sLog = org.apache.log4j.Logger.getLogger(SectionLimitCheck.class);
043        private static DecimalFormat sDF = new DecimalFormat("0.000");
044        private StudentSectioningModel iModel;
045        
046        /** Constructor
047         * @param model student sectioning model
048         */
049        public SectionLimitCheck(StudentSectioningModel model) {
050            iModel = model;
051        }
052        
053        /** Return student sectioning model */
054        public StudentSectioningModel getModel() {
055            return iModel;
056        }
057        
058        /** Check for sections that have more students enrolled than it is allowed, i.e.,
059         * the sum of requests weights is above the section limit
060         * @return false, if there is such a case
061         */
062        public boolean check() {
063            sLog.info("Checking section limits...");
064            boolean ret = true;
065            for (Enumeration e=getModel().getOfferings().elements();e.hasMoreElements();) {
066                Offering offering = (Offering)e.nextElement();
067                for (Enumeration f=offering.getConfigs().elements();f.hasMoreElements();) {
068                    Config config = (Config)f.nextElement();
069                    for (Enumeration g=config.getSubparts().elements();g.hasMoreElements();) {
070                        Subpart subpart = (Subpart)g.nextElement();
071                        for (Enumeration h=subpart.getSections().elements();h.hasMoreElements();) {
072                            Section section = (Section)h.nextElement();
073                            if (section.getLimit()<0) continue;
074                            double used = section.getEnrollmentWeight(null);
075                            if (used-section.getMaxEnrollmentWeight()>section.getLimit()) {
076                                sLog.error("Section "+section.getName()+" exceeds its limit "+sDF.format(used)+">"+section.getLimit()+" for more than one student (W:"+section.getMaxEnrollmentWeight()+")");
077                                ret = false;
078                            } else if (Math.round(used)>section.getLimit()) {
079                                sLog.debug("Section "+section.getName()+" exceeds its limit "+sDF.format(used)+">"+section.getLimit()+" for less than one student (W:"+section.getMaxEnrollmentWeight()+")");
080                            }
081                        }
082                    }
083                }
084            }
085            return ret;
086        }
087        
088    
089    }