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}