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