001    package net.sf.cpsolver.studentsct;
002    
003    import java.io.File;
004    import java.io.FileOutputStream;
005    import java.text.DecimalFormat;
006    import java.util.Collections;
007    import java.util.Comparator;
008    import java.util.Enumeration;
009    import java.util.Iterator;
010    
011    import net.sf.cpsolver.coursett.Constants;
012    import net.sf.cpsolver.ifs.util.DataProperties;
013    import net.sf.cpsolver.ifs.util.ToolBox;
014    import net.sf.cpsolver.studentsct.model.Course;
015    import net.sf.cpsolver.studentsct.model.CourseRequest;
016    import net.sf.cpsolver.studentsct.model.Enrollment;
017    import net.sf.cpsolver.studentsct.model.FreeTimeRequest;
018    import net.sf.cpsolver.studentsct.model.Request;
019    import net.sf.cpsolver.studentsct.model.Section;
020    import net.sf.cpsolver.studentsct.model.Student;
021    
022    import org.dom4j.Document;
023    import org.dom4j.DocumentHelper;
024    import org.dom4j.Element;
025    import org.dom4j.io.OutputFormat;
026    import org.dom4j.io.XMLWriter;
027    
028    /**
029     * This class exports student course and free time requests in a format as defined in this
030     * <a href='http://www.unitime.org/interface/StudentSectioning.dtd'>Student Sectioning DTD</a>. 
031     * See this <a href='http://www.unitime.org/interface/studentSectioningRequest.xml'>example</a> file.
032     *
033     * @version
034     * StudentSct 1.1 (Student Sectioning)<br>
035     * Copyright (C) 2007 Tomáš Müller<br>
036     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
037     * Lazenska 391, 76314 Zlin, Czech Republic<br>
038     * <br>
039     * This library is free software; you can redistribute it and/or
040     * modify it under the terms of the GNU Lesser General Public
041     * License as published by the Free Software Foundation; either
042     * version 2.1 of the License, or (at your option) any later version.
043     * <br><br>
044     * This library is distributed in the hope that it will be useful,
045     * but WITHOUT ANY WARRANTY; without even the implied warranty of
046     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
047     * Lesser General Public License for more details.
048     * <br><br>
049     * You should have received a copy of the GNU Lesser General Public
050     * License along with this library; if not, write to the Free Software
051     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
052     *
053     */
054    
055    public class StudentRequestXml {
056        private static DecimalFormat s2zDF = new DecimalFormat("00");
057        
058        public static Document exportModel(StudentSectioningModel model) {
059            Document document = DocumentHelper.createDocument();
060            Element requestElement = document.addElement("request");
061            requestElement.addAttribute("campus", model.getProperties().getProperty("Data.Initiative"));
062            requestElement.addAttribute("year", model.getProperties().getProperty("Data.Year"));
063            requestElement.addAttribute("term", model.getProperties().getProperty("Data.Term"));
064            for (Enumeration e=model.getStudents().elements();e.hasMoreElements();) {
065                Student student = (Student)e.nextElement();
066                Element studentElement = requestElement.addElement("student");
067                studentElement.addAttribute("key",String.valueOf(student.getId()));
068                Element courseRequestsElement = studentElement.addElement("updateCourseRequests");
069                courseRequestsElement.addAttribute("commit", "true");
070                Collections.sort(student.getRequests(),new Comparator() {
071                   public int compare(Object o1, Object o2) {
072                       Request r1 = (Request)o1;
073                       Request r2 = (Request)o2;
074                       if (r1.isAlternative()!=r2.isAlternative()) {
075                           return (r1.isAlternative()?1:-1);
076                       }
077                       return Double.compare(r1.getPriority(), r2.getPriority());
078                   }
079                });
080                boolean hasSchedule = false;
081                for (Enumeration f=student.getRequests().elements();f.hasMoreElements();) {
082                    Request request = (Request)f.nextElement();
083                    if (request.getAssignment()!=null) hasSchedule = true;
084                    if (request instanceof FreeTimeRequest) {
085                        FreeTimeRequest ftReq = (FreeTimeRequest)request;
086                        Element ftReqElement = courseRequestsElement.addElement("freeTime");
087                        requestElement.addAttribute("days", ftReq.getTime().getDayHeader());
088                        int startSlot = ftReq.getTime().getStartSlot();
089                        int startTime = startSlot*Constants.SLOT_LENGTH_MIN+Constants.FIRST_SLOT_TIME_MIN;
090                        ftReqElement.addAttribute("startTime", s2zDF.format(startTime/60)+s2zDF.format(startTime%60));
091                        int endTime = startTime + ftReq.getTime().getLength()*Constants.SLOT_LENGTH_MIN - ftReq.getTime().getBreakTime();
092                        ftReqElement.addAttribute("endTime", s2zDF.format(endTime/60)+s2zDF.format(endTime%60));
093                        ftReqElement.addAttribute("length", String.valueOf(ftReq.getTime().getLength()*Constants.SLOT_LENGTH_MIN));
094                    } else {
095                        CourseRequest crReq = (CourseRequest)request;
096                        Element crReqElement = courseRequestsElement.addElement("courseOffering");
097                        Course course = (Course)crReq.getCourses().firstElement();
098                        crReqElement.addAttribute("subjectArea", course.getSubjectArea());
099                        crReqElement.addAttribute("courseNumber", course.getCourseNumber());
100                        crReqElement.addAttribute("waitlist", crReq.isWaitlist()?"true":"false");
101                        crReqElement.addAttribute("alternative", crReq.isAlternative()?"true":"false");
102                        for (int i=1;i<crReq.getCourses().size();i++) {
103                            Course altCourse = (Course)crReq.getCourses().elementAt(i);
104                            Element altCourseElement = crReqElement.addElement("alternative");
105                            altCourseElement.addAttribute("subjectArea",altCourse.getSubjectArea());
106                            altCourseElement.addAttribute("courseNumber",altCourse.getCourseNumber());
107                        }
108                    }
109                }
110                if (hasSchedule) {
111                    Element requestScheduleElement = studentElement.addElement("requestSchedule");
112                    requestScheduleElement.addAttribute("type", "commit");
113                    for (Enumeration f=student.getRequests().elements();f.hasMoreElements();) {
114                        Request request = (Request)f.nextElement();
115                        if (request instanceof CourseRequest) {
116                            CourseRequest crReq = (CourseRequest)request;
117                            Enrollment enrollment = (Enrollment)crReq.getAssignment();
118                            if (enrollment==null) continue;
119                            Element crReqElement = requestScheduleElement.addElement("courseOffering");
120                            Course course = enrollment.getConfig().getOffering().getCourse(student);
121                            crReqElement.addAttribute("subjectArea", course.getSubjectArea());
122                            crReqElement.addAttribute("courseNumber", course.getCourseNumber());
123                            for (Iterator i=enrollment.getAssignments().iterator();i.hasNext();) {
124                                Section section = (Section)i.next();
125                                Element classEl = crReqElement.addElement("class");
126                                classEl.addAttribute("id", section.getSubpart().getInstructionalType());
127                                classEl.addAttribute("assignmentId", String.valueOf(section.getId()));
128                            }
129                        }
130                    }                
131                }
132            }
133            return document;
134        }
135        
136        public static void main(String[] args) {
137            try {
138                ToolBox.configureLogging();
139                StudentSectioningModel model = new StudentSectioningModel(new DataProperties());
140                StudentSectioningXMLLoader xmlLoad = new StudentSectioningXMLLoader(model);
141                xmlLoad.setInputFile(new File(args[0]));
142                xmlLoad.load();
143                Document document = exportModel(model);
144                FileOutputStream fos = new FileOutputStream(new File(args[1]));
145                (new XMLWriter(fos,OutputFormat.createPrettyPrint())).write(document);
146                fos.flush();
147                fos.close();
148            } catch (Exception e) {
149                e.printStackTrace();
150            }
151        }
152    }