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.Request.RequestPriority; 021import org.cpsolver.studentsct.model.Section; 022import org.cpsolver.studentsct.model.Student; 023import org.dom4j.Document; 024import org.dom4j.DocumentHelper; 025import org.dom4j.Element; 026import org.dom4j.io.OutputFormat; 027import org.dom4j.io.XMLWriter; 028 029/** 030 * This class exports student course and free time requests in a format as 031 * defined in this <a 032 * href='http://www.unitime.org/interface/StudentSectioning.dtd'>Student 033 * Sectioning DTD</a>. See this <a href= 034 * 'http://www.unitime.org/interface/studentSectioningRequest.xml'>example</a> 035 * file. 036 * 037 * @version StudentSct 1.3 (Student Sectioning)<br> 038 * Copyright (C) 2007 - 2014 Tomáš Müller<br> 039 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 040 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 041 * <br> 042 * This library is free software; you can redistribute it and/or modify 043 * it under the terms of the GNU Lesser General Public License as 044 * published by the Free Software Foundation; either version 3 of the 045 * License, or (at your option) any later version. <br> 046 * <br> 047 * This library is distributed in the hope that it will be useful, but 048 * WITHOUT ANY WARRANTY; without even the implied warranty of 049 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 050 * Lesser General Public License for more details. <br> 051 * <br> 052 * You should have received a copy of the GNU Lesser General Public 053 * License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 054 * 055 */ 056 057public class StudentRequestXml { 058 private static DecimalFormat s2zDF = new DecimalFormat("00"); 059 060 public static Document exportModel(Assignment<Request, Enrollment> assignment, StudentSectioningModel model) { 061 Document document = DocumentHelper.createDocument(); 062 Element requestElement = document.addElement("request"); 063 requestElement.addAttribute("campus", model.getProperties().getProperty("Data.Initiative")); 064 requestElement.addAttribute("year", model.getProperties().getProperty("Data.Year")); 065 requestElement.addAttribute("term", model.getProperties().getProperty("Data.Term")); 066 for (Student student : model.getStudents()) { 067 Element studentElement = requestElement.addElement("student"); 068 studentElement.addAttribute("key", String.valueOf(student.getId())); 069 Element courseRequestsElement = studentElement.addElement("updateCourseRequests"); 070 courseRequestsElement.addAttribute("commit", "true"); 071 Collections.sort(student.getRequests(), new Comparator<Request>() { 072 @Override 073 public int compare(Request r1, Request r2) { 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 (Request request : student.getRequests()) { 082 if (assignment.getValue(request) != null) 083 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 092 - ftReq.getTime().getBreakTime(); 093 ftReqElement.addAttribute("endTime", s2zDF.format(endTime / 60) + s2zDF.format(endTime % 60)); 094 ftReqElement.addAttribute("length", String.valueOf(ftReq.getTime().getLength() 095 * Constants.SLOT_LENGTH_MIN)); 096 } else { 097 CourseRequest crReq = (CourseRequest) request; 098 Element crReqElement = courseRequestsElement.addElement("courseOffering"); 099 Course course = crReq.getCourses().get(0); 100 crReqElement.addAttribute("subjectArea", course.getSubjectArea()); 101 crReqElement.addAttribute("courseNumber", course.getCourseNumber()); 102 crReqElement.addAttribute("waitlist", crReq.isWaitlist() ? "true" : "false"); 103 crReqElement.addAttribute("critical", crReq.getRequestPriority() == RequestPriority.Critical ? "true" : "false"); 104 crReqElement.addAttribute("importance", crReq.getRequestPriority().name()); 105 crReqElement.addAttribute("alternative", crReq.isAlternative() ? "true" : "false"); 106 for (int i = 1; i < crReq.getCourses().size(); i++) { 107 Course altCourse = crReq.getCourses().get(i); 108 Element altCourseElement = crReqElement.addElement("alternative"); 109 altCourseElement.addAttribute("subjectArea", altCourse.getSubjectArea()); 110 altCourseElement.addAttribute("courseNumber", altCourse.getCourseNumber()); 111 } 112 } 113 } 114 if (hasSchedule) { 115 Element requestScheduleElement = studentElement.addElement("requestSchedule"); 116 requestScheduleElement.addAttribute("type", "commit"); 117 for (Request request : student.getRequests()) { 118 if (request instanceof CourseRequest) { 119 CourseRequest crReq = (CourseRequest) request; 120 Enrollment enrollment = assignment.getValue(crReq); 121 if (enrollment == null) 122 continue; 123 Element crReqElement = requestScheduleElement.addElement("courseOffering"); 124 Course course = enrollment.getCourse(); 125 crReqElement.addAttribute("subjectArea", course.getSubjectArea()); 126 crReqElement.addAttribute("courseNumber", course.getCourseNumber()); 127 for (Section section : enrollment.getSections()) { 128 Element classEl = crReqElement.addElement("class"); 129 classEl.addAttribute("id", section.getSubpart().getInstructionalType()); 130 classEl.addAttribute("assignmentId", String.valueOf(section.getId())); 131 } 132 } 133 } 134 } 135 } 136 return document; 137 } 138 139 public static void main(String[] args) { 140 try { 141 ToolBox.configureLogging(); 142 StudentSectioningModel model = new StudentSectioningModel(new DataProperties()); 143 Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>(); 144 StudentSectioningXMLLoader xmlLoad = new StudentSectioningXMLLoader(model, assignment); 145 xmlLoad.setInputFile(new File(args[0])); 146 xmlLoad.load(); 147 Document document = exportModel(assignment, model); 148 FileOutputStream fos = new FileOutputStream(new File(args[1])); 149 (new XMLWriter(fos, OutputFormat.createPrettyPrint())).write(document); 150 fos.flush(); 151 fos.close(); 152 } catch (Exception e) { 153 e.printStackTrace(); 154 } 155 } 156}