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