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