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.ExamInstructor;
008    import net.sf.cpsolver.exam.model.ExamModel;
009    import net.sf.cpsolver.exam.model.ExamOwner;
010    import net.sf.cpsolver.exam.model.ExamPeriod;
011    import net.sf.cpsolver.exam.model.ExamPlacement;
012    import net.sf.cpsolver.exam.model.ExamRoomPlacement;
013    import net.sf.cpsolver.ifs.util.CSVFile;
014    import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
015    
016    /**
017     * Export instructor 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 ExamInstructorConflicts(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 ExamInstructorConflicts {
047        private ExamModel iModel = null;
048        
049        /**
050         * Constructor
051         * @param model examination timetabling model
052         */
053        public ExamInstructorConflicts(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("Instructor"),
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.getInstructors().elements();e.hasMoreElements();) {
073                ExamInstructor instructor = (ExamInstructor)e.nextElement();
074                for (Enumeration f=iModel.getPeriods().elements();f.hasMoreElements();) {
075                    ExamPeriod period = (ExamPeriod)f.nextElement();
076                    int nrExams = instructor.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=instructor.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(instructor).elements();g.hasMoreElements();){
094                                ExamOwner owner = (ExamOwner)g.nextElement();
095                                if (sections.length()>0) { 
096                                    sections+="\n"; rooms+="\n";
097                                    periods+="\n"; periodDays+="\n"; periodTimes+="\n";
098                                }
099                                sections += owner.getName();
100                                if (first) rooms += roomsThisExam;
101                                first = false;
102                            }
103                            if (exam.getOwners(instructor).isEmpty()) {
104                                sections += exam.getName();
105                                rooms += roomsThisExam;
106                            }
107                        }
108                        csv.addLine(new CSVField[] {
109                                new CSVField(instructor.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 && !instructor.getExams(period.next()).isEmpty() && (!iModel.isDayBreakBackToBack() || period.next().getDay()==period.getDay())) {
120                            for (Iterator i=instructor.getExams(period).iterator();i.hasNext();) {
121                                Exam ex1 = (Exam)i.next();
122                                for (Iterator j=instructor.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(instructor).elements();g.hasMoreElements();){
138                                        ExamOwner owner = (ExamOwner)g.nextElement();
139                                        if (sections.length()>0) {
140                                            sections+="\n"; rooms+="\n";
141                                            periods+="\n"; periodDays+="\n"; periodTimes+="\n";
142                                        }
143                                        sections += owner.getName();
144                                        if (first) rooms += roomsThisExam;
145                                        first = false;
146                                    }
147                                    if (ex1.getOwners(instructor).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(instructor).elements();g.hasMoreElements();){
160                                        ExamOwner owner = (ExamOwner)g.nextElement();
161                                        sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n";
162                                        sections += owner.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(instructor).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                                    }
179                                    String distStr="";
180                                    if (iModel.getBackToBackDistance()>=0) {
181                                        int dist = ((ExamPlacement)ex1.getAssignment()).getDistance((ExamPlacement)ex2.getAssignment());
182                                        if (dist>0) distStr = String.valueOf(dist);
183                                    }
184                                    csv.addLine(new CSVField[] {
185                                            new CSVField(instructor.getName()),
186                                            new CSVField("back-to-back"),
187                                            new CSVField(sections),
188                                            new CSVField(periods),
189                                            new CSVField(periodDays),
190                                            new CSVField(periodTimes),
191                                            new CSVField(rooms),
192                                            new CSVField(distStr)
193                                    });
194                                }
195                            }
196                        }
197                    }
198                    if (period.next()==null || period.next().getDay()!=period.getDay()) {
199                        int nrExamsADay = instructor.getExamsADay(period.getDay()).size();
200                        if (nrExamsADay>2) {
201                            String sections = "";
202                            String periods = "";
203                            String periodDays = "";
204                            String periodTimes = "";
205                            String rooms = "";
206                            for (Iterator i=instructor.getExamsADay(period.getDay()).iterator();i.hasNext();) {
207                                Exam exam = (Exam)i.next();
208                                ExamPlacement placement = (ExamPlacement)exam.getAssignment();
209                                String roomsThisExam = "";
210                                for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
211                                    ExamRoomPlacement room = (ExamRoomPlacement)k.next();
212                                    if (roomsThisExam.length()>0) roomsThisExam+=", ";
213                                    roomsThisExam+=room.getName();
214                                }
215                                boolean first = true;
216                                for (Enumeration g=exam.getOwners(instructor).elements();g.hasMoreElements();){
217                                    ExamOwner owner = (ExamOwner)g.nextElement();
218                                    if (sections.length()>0) {
219                                        sections+="\n"; rooms+="\n";
220                                        periods+="\n"; periodDays+="\n"; periodTimes+="\n";
221                                    }
222                                    sections += owner.getName();
223                                    if (first) {
224                                        periods += (placement.getPeriod().getIndex()+1);
225                                        periodDays += placement.getPeriod().getDayStr();
226                                        periodTimes += placement.getPeriod().getTimeStr();
227                                        rooms += roomsThisExam;
228                                    }
229                                    first = false;
230                                }
231                                if (exam.getOwners(instructor).isEmpty()) {
232                                    if (sections.length()>0) {
233                                        sections+="\n"; rooms+="\n";
234                                        periods+="\n"; periodDays+="\n"; periodTimes+="\n";
235                                    }
236                                    sections += exam.getName();
237                                    periods += (placement.getPeriod().getIndex()+1);
238                                    periodDays += placement.getPeriod().getDayStr();
239                                    periodTimes += placement.getPeriod().getTimeStr();
240                                    rooms += roomsThisExam;
241                                }
242                            }
243                            csv.addLine(new CSVField[] {
244                                    new CSVField(instructor.getName()),
245                                    new CSVField("more-2-day"),
246                                    new CSVField(sections),
247                                    new CSVField(periods),
248                                    new CSVField(periodDays),
249                                    new CSVField(periodTimes),
250                                    new CSVField(rooms)
251                            });
252                        }
253                    }
254                }
255            }
256            return csv;
257        }
258    }