/**
* Loads and saves from and to XML files.
*
* @author Brett M. Story
* @date 13 October, 2013
*/
package io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import objects.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
public class parseXML {
private static MyCourse course;
private static MyCourse loadCourseInfo(File file) {
course = new MyCourse(null);
try {
// Initial setup of document parser
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(file);
// normalize text representation
doc.getDocumentElement().normalize();
/* ------------------------------
* Section for courseName
* -------------------------------*/
NodeList courseNameList = doc.getElementsByTagName("courseName");
Node courseNameNode = courseNameList.item(0);
//Note: you must do .getFirstChild().getNodeValue() to return what's inside the tags
course.setName(courseNameNode.getFirstChild().getNodeValue());
/* ------------------------------
* Section for courseID/#/Section
* -------------------------------*/
NodeList courseIDList = doc.getElementsByTagName("courseID");
Node courseIDNode = courseIDList.item(0);
course.setCourseID(courseIDNode.getFirstChild().getNodeValue());
NodeList courseNumberList = doc.getElementsByTagName("courseNumber");
Node courseNumberNode = courseNumberList.item(0);
course.setCourseNumber(Integer.parseInt(courseNumberNode.getFirstChild().getNodeValue()));
NodeList sectionList = doc.getElementsByTagName("section");
Node sectionNode = sectionList.item(0);
course.setSection(sectionNode.getFirstChild().getNodeValue());
/* ------------------------------
* Section for building/roomNumber
* -------------------------------*/
NodeList buildingList = doc.getElementsByTagName("building");
Node buildingNode = buildingList.item(0);
Node buildingTextNode = buildingNode.getFirstChild();
if (buildingTextNode != null) {
course.setBuilding(buildingTextNode.getNodeValue());
}
NodeList roomIDList = doc.getElementsByTagName("roomID");
Node roomIDNode = roomIDList.item(0);
Node roomIDTextNode = roomIDNode.getFirstChild();
if (roomIDTextNode != null) {
course.setRoomID(roomIDTextNode.getNodeValue());
}
/* ------------------------------
* Section for meetingTime
* -------------------------------*/
NodeList meetingTimeList = doc.getElementsByTagName("meetingTime");
Node meetingTimeNode = meetingTimeList.item(0);
Node meetingTimeTextNode = meetingTimeNode.getFirstChild();
if (meetingTimeTextNode != null) {
course.setMeetingTime(meetingTimeTextNode.getNodeValue());
}
/* ------------------------------
* Section for semester
* -------------------------------*/
NodeList semesterList = doc.getElementsByTagName("semester");
Node semesterNode = semesterList.item(0);
course.setSemester(semesterNode.getFirstChild().getNodeValue());
Node semesterTextNode = semesterNode.getFirstChild();
if (semesterTextNode != null) {
course.setSemester(semesterTextNode.getNodeValue());
}
/* ------------------------------
* Section for index
* -------------------------------*/
NodeList indexList = doc.getElementsByTagName("index");
Node assignmentNode = indexList.item(0);
Node categoryNode = indexList.item(1);
if (assignmentNode.getFirstChild().getNodeValue().equals("null") || categoryNode.getFirstChild().getNodeValue().equals("null")) {
course.setLastAssignmentIndex(null);
course.setLastCategoryIndex(null);
}
else {
course.setLastAssignmentIndex(Integer.parseInt(assignmentNode.getFirstChild().getNodeValue()));
course.setLastCategoryIndex(Integer.parseInt(categoryNode.getFirstChild().getNodeValue()));
}
//Beyond this point are all catches
}catch (SAXParseException err)
{
System.out.println("** Parsing error" + ", line " +
err.getLineNumber() + ", uri " + err.getSystemId());
System.out.println(" " + err.getMessage());
}catch (SAXException e) {
// TODO Auto-generated catch block
Exception x = e.getException();
((x == null) ? e: x).printStackTrace();
}catch (Throwable t) {
// TODO Auto-generated catch block
t.printStackTrace();
}
return course;
}
private static void loadStudentInfo(File file) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
String firstName = null;
String lastName = null;
String psuedoName = null;
boolean isFirstName = false;
boolean isLastName = false;
boolean isPsuedoName = false;
boolean isGhostName = false;
// A SAX callback method which finds the start of an XML element
public void startElement (String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("firstName")) {
isFirstName = true;
}
if (qName.equalsIgnoreCase("lastName")) {
isLastName = true;
}
if (qName.equalsIgnoreCase("psuedoName")) {
isPsuedoName = true;
}
if (qName.equalsIgnoreCase("ghostName")) {
isGhostName = true;
}
}
// A SAX callback method which finds the end of an XML element
public void endElement(String uri, String localName,
String qName) throws SAXException {
// adds a student to course when it reaches </student>
if (qName.equalsIgnoreCase("student")) {
course.addStudentXML(firstName, lastName, psuedoName);
}
}
// A SAX callback method which contains all the characters in an element
public void characters(char ch[], int start, int length)
throws SAXException {
//If the element is <name>
if (isFirstName) {
firstName = new String(ch, start, length);
isFirstName = false; // must declare name false for next search
}
//If the element is <name>
if (isLastName) {
lastName = new String(ch, start, length);
isLastName = false; // must declare name false for next search
}
//If the element is <psuedoName>
if (isPsuedoName) {
psuedoName = new String(ch, start, length);
isPsuedoName = false;
}
if (isGhostName) {
course.addGhostStudentXML(new String(ch, start, length));
isGhostName = false;
}
}
};
saxParser.parse(file, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void loadAssignmentInfo(File file) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler()
{
String assignmentName;
int assignmentWorth;
String currentCategoryName;
int currentCategoryIndex = 0;
boolean isCategoryName = false;
boolean isAssignmentName = false;
boolean isWorth = false;
boolean isGrade = false;
int studentIndex = 0;
int totalStudents = course.getNumberOfStudents();
// A SAX callback method which finds the start of an XML element
public void startElement (String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("categoryName")) {
isCategoryName = true;
}
if (qName.equalsIgnoreCase("assignmentName")) {
isAssignmentName = true;
}
if (qName.equalsIgnoreCase("worth")) {
isWorth = true;
}
if (qName.equalsIgnoreCase("grade")) {
isGrade = true;
}
}
// A SAX callback method which finds the end of an XML element
public void endElement(String uri, String localName,
String qName) throws SAXException {
if (qName.equalsIgnoreCase("assignment")) {
studentIndex = 0;
}
}
// A SAX callback method which contains all the characters in an element
public void characters(char ch[], int start, int length)
throws SAXException {
if (isCategoryName) {
currentCategoryName = new String(ch, start, length);
course.addAssignmentCategory(currentCategoryName);
currentCategoryIndex = course.getAssignmentCategoryIndex(currentCategoryName);
isCategoryName = false;
}
if (isAssignmentName) {
assignmentName = new String(ch, start, length);
isAssignmentName = false;
}
if (isWorth) {
assignmentWorth = Integer.parseInt(new String(ch, start, length));
course.getAssignmentCategory(currentCategoryIndex).addAssignment(assignmentName, assignmentWorth);
isWorth = false;
}
if (isGrade) {
AssignmentCategory currentCategory = course.getAssignmentCategory(currentCategoryIndex);
Assignment currentAssignment = currentCategory.getAssignment(currentCategory.getAssignmentIndex(assignmentName));
String gradeValue = new String(ch, start, length);
String pseudoName = null;
boolean student = false;
if (studentIndex < totalStudents) {
pseudoName = course.getStudent(studentIndex).getPseudoName();
student = true;
}
else {
pseudoName = course.getGhostStudent(studentIndex - totalStudents).getPseudoName();
}
if (gradeValue.equals("null") || gradeValue.equals("")) {
currentAssignment.setGrade(pseudoName, null, student);
}
else {
currentAssignment.setGrade(pseudoName, Integer.parseInt(gradeValue), student);
}
isGrade = false;
studentIndex ++;
}
}
};
saxParser.parse(file, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
public static MyCourse loadXML(File file) {
course = loadCourseInfo(file);
loadStudentInfo(file);
loadAssignmentInfo(file);
return course;
}
public static void saveXML(MyCourse tmpCourse) {
String fileDir = "gradebooks" + File.separator + tmpCourse.getIdentifier() + ".xml";
File file = new File(fileDir);
if (file.exists())
file.delete();
try {
file.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
//Add header of XML file
writer.write("<class id=\""+file.toString()+"\">\n");
//FIXME use non-OS-specific newlines
//Add general course information to file
writer.write("\t<courseName>" + tmpCourse.getName() + "</courseName>\n");
writer.write("\t<courseID>" + tmpCourse.getCourseID() + "</courseID>\n");
writer.write("\t<courseNumber>" + tmpCourse.getCourseNumber() + "</courseNumber>\n");
writer.write("\t<section>" + tmpCourse.getSection() + "</section>\n");
writer.write("\t<building>" + tmpCourse.getBuilding() + "</building>\n");
writer.write("\t<roomID>" + tmpCourse.getRoomID() + "</roomID>\n");
writer.write("\t<meetingTime>" + tmpCourse.getMeetingTime() + "</meetingTime>\n");
writer.write("\t<semester>" + tmpCourse.getSemester() + "</semester>\n");
if (tmpCourse.getLastAssignmentIndex() != null && tmpCourse.getLastCategoryIndex() != null
&& tmpCourse.getLastCategoryIndex() < tmpCourse.getNumberOfAssignmentCategories()
&& tmpCourse.getLastAssignmentIndex() < tmpCourse.getCategories().get(tmpCourse.getLastCategoryIndex()).getNumberOfAssignments()) {
writer.write("\t<index>" + tmpCourse.getLastAssignmentIndex() + "</index>\n");
writer.write("\t<index>" + tmpCourse.getLastCategoryIndex() + "</index>\n\n");
}
else {
writer.write("\t<index>null</index>\n");
writer.write("\t<index>null</index>\n\n");
}
//Add student information
for (int i = 0; i < tmpCourse.getNumberOfStudents(); i++) {
writer.write("\t<student>\n");
writer.write("\t\t<firstName>" + tmpCourse.getStudent(i).getFirstName() + "</firstName>\n");
writer.write("\t\t<lastName>" + tmpCourse.getStudent(i).getLastName() + "</lastName>\n");
writer.write("\t\t<psuedoName>" + tmpCourse.getStudent(i).getPseudoName() + "</psuedoName>\n");
writer.write("\t</student>\n");
}
writer.write("\t<!-- Ghost Students -->\n");
//Add ghost students
for (int i = 0; i <tmpCourse.getNumberOfGhostStudents(); i++) {
writer.write("\t<ghostStudent>\n");
writer.write("\t\t<ghostName>" + tmpCourse.getGhostStudent(i).getPseudoName() + "</ghostName>\n");
writer.write("\t</ghostStudent>\n");
}
//Add assignment information
for (int i = 0; i < tmpCourse.getNumberOfAssignmentCategories(); i++) {
writer.write("\t<category>\n");
writer.write("\t\t<categoryName>" + tmpCourse.getAssignmentCategory(i).getName() + "</categoryName>\n");
for (int j = 0; j < tmpCourse.getAssignmentCategory(i).getNumberOfAssignments(); j++) {
writer.write("\t\t<assignment>\n");
writer.write("\t\t\t<assignmentName>" + tmpCourse.getAssignmentCategory(i).getAssignment(j).getName() + "</assignmentName>\n");
writer.write("\t\t\t<worth>" + tmpCourse.getAssignmentCategory(i).getAssignment(j).getWorth() + "</worth>\n");
for (int k = 0; k < tmpCourse.getNumberOfStudents(); k++) {
writer.write("\t\t\t<grade id=\"" + tmpCourse.getStudent(k).getFullName() + "\">" +
tmpCourse.getAssignmentCategory(i).getAssignment(j).getGrade(tmpCourse.getStudent(k).getPseudoName()) + "</grade>\n");
}
writer.write("\t\t\t<!-- Ghost Students -->\n");
for (int k = 0; k < tmpCourse.getNumberOfGhostStudents(); k++) {
writer.write("\t\t\t<grade id=\"" + tmpCourse.getGhostStudent(k).getPseudoName() + "\">" +
tmpCourse.getAssignmentCategory(i).getAssignment(j).getGrade(tmpCourse.getGhostStudent(k).getPseudoName()) + "</grade>\n");
}
writer.write("\t\t</assignment>\n");
}
writer.write("\t</category>\n");
}
writer.write("</class>");
} catch (IOException e){
System.out.println(e);
} finally {
try {writer.close();} catch (Exception e) {
System.out.println(e);
}
}
}
public static Boolean archiveCourse(MyCourse tmpCourse) {
String fileDir = "gradebooks" + File.separator + tmpCourse.getIdentifier() + ".xml";
String desiredDir = "gradebooks" + File.separator + "archive" + File.separator + tmpCourse.getIdentifier() + ".xml";
File desired = new File (desiredDir);
if (desired.exists())
desired.delete();
try {
File file = new File(fileDir);
if (file.renameTo(desired))
return true;
else
return false;
} catch(Exception e) {
e.printStackTrace();
}
return false;
}
/*
public static void main(String argv[]) {
course = loadXML(new File("structure.xml"));
course.removeStudent(7);
saveXML(course, new File("output.xml"));
}*/
}