001    package net.sf.cpsolver.exam.reports;
002    
003    import java.util.Enumeration;
004    import java.util.Iterator;
005    
006    import net.sf.cpsolver.exam.model.Exam;
007    import net.sf.cpsolver.exam.model.ExamModel;
008    import net.sf.cpsolver.exam.model.ExamOwner;
009    import net.sf.cpsolver.exam.model.ExamPeriod;
010    import net.sf.cpsolver.exam.model.ExamPlacement;
011    import net.sf.cpsolver.exam.model.ExamRoomPlacement;
012    import net.sf.cpsolver.exam.model.ExamStudent;
013    import net.sf.cpsolver.ifs.util.CSVFile;
014    import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
015    
016    /**
017     * Export student direct, back-to-back, and more than two exams a day conflicts 
018     * into a CSV file.
019     * <br><br>
020     * Usage:<br>
021     * <code>
022     * &nbsp;&nbsp;&nbsp;&nbsp;new ExamStudentConflicts(model).report().save(file);
023     * </code>
024     * <br><br>
025     * 
026     * @version
027     * ExamTT 1.1 (Examination Timetabling)<br>
028     * Copyright (C) 2008 Tomáš Müller<br>
029     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
030     * Lazenska 391, 76314 Zlin, Czech Republic<br>
031     * <br>
032     * This library is free software; you can redistribute it and/or
033     * modify it under the terms of the GNU Lesser General Public
034     * License as published by the Free Software Foundation; either
035     * version 2.1 of the License, or (at your option) any later version.
036     * <br><br>
037     * This library is distributed in the hope that it will be useful,
038     * but WITHOUT ANY WARRANTY; without even the implied warranty of
039     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
040     * Lesser General Public License for more details.
041     * <br><br>
042     * You should have received a copy of the GNU Lesser General Public
043     * License along with this library; if not, write to the Free Software
044     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
045     */
046    public class ExamStudentConflicts {
047        private ExamModel iModel = null;
048        
049        /**
050         * Constructor
051         * @param model examination timetabling model
052         */
053        public ExamStudentConflicts(ExamModel model) {
054            iModel = model;
055        }
056        
057        /**
058         * generate report
059         */
060        public CSVFile report() {
061            CSVFile csv = new CSVFile();
062            csv.setHeader(new CSVField[] {
063                    new CSVField("Student"),
064                    new CSVField("Type"),
065                    new CSVField("Section/Course"),
066                    new CSVField("Period"),
067                    new CSVField("Day"),
068                    new CSVField("Time"),
069                    new CSVField("Room"),
070                    new CSVField("Distance")
071            });
072            for (Enumeration e=iModel.getStudents().elements();e.hasMoreElements();) {
073                ExamStudent student = (ExamStudent)e.nextElement();
074                for (Enumeration f=iModel.getPeriods().elements();f.hasMoreElements();) {
075                    ExamPeriod period = (ExamPeriod)f.nextElement();
076                    int nrExams = student.getExams(period).size();
077                    if (nrExams>1) {
078                        String sections = "";
079                        String rooms = "";
080                        String periods = String.valueOf(period.getIndex()+1);
081                        String periodDays = period.getDayStr();
082                        String periodTimes = period.getTimeStr();
083                        for (Iterator i=student.getExams(period).iterator();i.hasNext();) {
084                            Exam exam = (Exam)i.next();
085                            ExamPlacement placement = (ExamPlacement)exam.getAssignment();
086                            String roomsThisExam = "";
087                            for (Iterator j=placement.getRoomPlacements().iterator();j.hasNext();) {
088                                ExamRoomPlacement room = (ExamRoomPlacement)j.next();
089                                if (roomsThisExam.length()>0) roomsThisExam+=", ";
090                                roomsThisExam+=room.getName();
091                            }
092                            boolean first = true;
093                            for (Enumeration g=exam.getOwners(student).elements();g.hasMoreElements();){
094                                ExamOwner cs = (ExamOwner)g.nextElement();
095                                if (sections.length()>0) { 
096                                    sections+="\n"; rooms+="\n";
097                                    periods+="\n"; periodDays+="\n"; periodTimes+="\n";
098                                }
099                                sections += cs.getName();
100                                if (first) rooms += roomsThisExam;
101                                first = false;
102                            }
103                            if (exam.getOwners(student).isEmpty()) {
104                                sections += exam.getName();
105                                rooms += roomsThisExam;
106                            }
107                        }
108                        csv.addLine(new CSVField[] {
109                                new CSVField(student.getName()),
110                                new CSVField("direct"),
111                                new CSVField(sections),
112                                new CSVField(periods),
113                                new CSVField(periodDays),
114                                new CSVField(periodTimes),
115                                new CSVField(rooms)
116                        });
117                    }
118                    if (nrExams>0) {
119                        if (period.next()!=null && !student.getExams(period.next()).isEmpty() && (!iModel.isDayBreakBackToBack() || period.next().getDay()==period.getDay())) {
120                            for (Iterator i=student.getExams(period).iterator();i.hasNext();) {
121                                Exam ex1 = (Exam)i.next();
122                                for (Iterator j=student.getExams(period.next()).iterator();j.hasNext();) {
123                                    Exam ex2 = (Exam)j.next();
124                                    ExamPlacement placement = (ExamPlacement)ex1.getAssignment();
125                                    String sections = "";
126                                    String rooms = "";
127                                    String roomsThisExam = "";
128                                    String periods = String.valueOf(period.getIndex()+1);
129                                    String periodDays = period.getDayStr();
130                                    String periodTimes = period.getTimeStr();
131                                    for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
132                                        ExamRoomPlacement room = (ExamRoomPlacement)k.next();
133                                        if (roomsThisExam.length()>0) roomsThisExam+=", ";
134                                        roomsThisExam+=room.getName();
135                                    }
136                                    boolean first = true;
137                                    for (Enumeration g=ex1.getOwners(student).elements();g.hasMoreElements();){
138                                        ExamOwner cs = (ExamOwner)g.nextElement();
139                                        if (sections.length()>0) {
140                                            sections+="\n"; rooms+="\n";
141                                            periods+="\n"; periodDays+="\n"; periodTimes+="\n";
142                                        }
143                                        sections += cs.getName();
144                                        if (first) rooms += roomsThisExam;
145                                        first = false;
146                                    }
147                                    if (ex1.getOwners(student).isEmpty()) {
148                                        sections += ex1.getName();
149                                        rooms += roomsThisExam;
150                                    }
151                                    placement = (ExamPlacement)ex2.getAssignment();
152                                    roomsThisExam = "";
153                                    for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
154                                        ExamRoomPlacement room = (ExamRoomPlacement)k.next();
155                                        if (roomsThisExam.length()>0) roomsThisExam+=", ";
156                                        roomsThisExam+=room.getName();
157                                    }
158                                    first = true;
159                                    for (Enumeration g=ex2.getOwners(student).elements();g.hasMoreElements();){
160                                        ExamOwner cs = (ExamOwner)g.nextElement();
161                                        sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n";
162                                        sections += cs.getName();
163                                        if (first) {
164                                            rooms += roomsThisExam;
165                                            periods += String.valueOf(period.next().getIndex()+1);
166                                            periodDays += period.next().getDayStr();
167                                            periodTimes += period.next().getTimeStr();
168                                        }
169                                        first = false;
170                                    }
171                                    if (ex2.getOwners(student).isEmpty()) {
172                                        sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n";
173                                        sections += ex2.getName();
174                                        rooms += roomsThisExam;
175                                        periods += String.valueOf(period.next().getIndex()+1);
176                                        periodDays += period.next().getDayStr();
177                                        periodTimes += period.next().getTimeStr();
178                                        rooms += roomsThisExam;
179                                    }
180                                    String distStr="";
181                                    if (iModel.getBackToBackDistance()>=0) {
182                                        int dist = ((ExamPlacement)ex1.getAssignment()).getDistance((ExamPlacement)ex2.getAssignment());
183                                        if (dist>0) distStr = String.valueOf(dist);
184                                    }
185                                    csv.addLine(new CSVField[] {
186                                            new CSVField(student.getName()),
187                                            new CSVField("back-to-back"),
188                                            new CSVField(sections),
189                                            new CSVField(periods),
190                                            new CSVField(periodDays),
191                                            new CSVField(periodTimes),
192                                            new CSVField(rooms),
193                                            new CSVField(distStr)
194                                    });
195                                }
196                            }
197                        }
198                    }
199                    if (period.next()==null || period.next().getDay()!=period.getDay()) {
200                        int nrExamsADay = student.getExamsADay(period.getDay()).size();
201                        if (nrExamsADay>2) {
202                            String sections = "";
203                            String periods = "";
204                            String periodDays = "";
205                            String periodTimes = "";
206                            String rooms = "";
207                            for (Iterator i=student.getExamsADay(period.getDay()).iterator();i.hasNext();) {
208                                Exam exam = (Exam)i.next();
209                                ExamPlacement placement = (ExamPlacement)exam.getAssignment();
210                                String roomsThisExam = "";
211                                for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
212                                    ExamRoomPlacement room = (ExamRoomPlacement)k.next();
213                                    if (roomsThisExam.length()>0) roomsThisExam+=", ";
214                                    roomsThisExam+=room.getName();
215                                }
216                                boolean first = true;
217                                for (Enumeration g=exam.getOwners(student).elements();g.hasMoreElements();){
218                                    ExamOwner cs = (ExamOwner)g.nextElement();
219                                    if (sections.length()>0) {
220                                        sections+="\n"; rooms+="\n";
221                                        periods+="\n"; periodDays+="\n"; periodTimes+="\n";
222                                    }
223                                    sections += cs.getName();
224                                    if (first) {
225                                        periods += (placement.getPeriod().getIndex()+1);
226                                        periodDays += placement.getPeriod().getDayStr();
227                                        periodTimes += placement.getPeriod().getTimeStr();
228                                        rooms += roomsThisExam;
229                                    }
230                                    first = false;
231                                }
232                                if (exam.getOwners(student).isEmpty()) {
233                                    if (sections.length()>0) {
234                                        sections+="\n"; rooms+="\n";
235                                        periods+="\n"; periodDays+="\n"; periodTimes+="\n";
236                                    }
237                                    sections += exam.getName();
238                                    periods += (placement.getPeriod().getIndex()+1);
239                                    periodDays += placement.getPeriod().getDayStr();
240                                    periodTimes += placement.getPeriod().getTimeStr();
241                                    rooms += roomsThisExam;
242                                }
243                            }
244                            csv.addLine(new CSVField[] {
245                                    new CSVField(student.getName()),
246                                    new CSVField("more-2-day"),
247                                    new CSVField(sections),
248                                    new CSVField(periods),
249                                    new CSVField(periodDays),
250                                    new CSVField(periodTimes),
251                                    new CSVField(rooms)
252                            });
253                        }
254                    }
255                }
256            }
257            return csv;
258        }
259    }