Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package edu.pdx.cs410J.grader.scoring;

/**
* Created by sushamkumar on 9/1/17.
*/
public class InvalidFileContentException extends Exception {
public InvalidFileContentException() { super("Out file is corrupted"); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this constructor ever called? If not, let's delete it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this constructor is never called for now. But, I have kept this so that If there isn't any message to provide then we could use this constructor. I will remove this, so that custom message makes more sense.

public InvalidFileContentException(String message) { super(message); }

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public class ProjectSubmission {
private Double score;
private String studentName;
private Date submissionTime;
private Date gradedTime;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Good call. Thank you for adding this.




public Date getGradedTime() {return gradedTime;}

public void setGradedTime(Date gradedTime) {this.gradedTime = gradedTime;}

public void setProjectName(String projectName) {
this.projectName = projectName;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,116 @@
package edu.pdx.cs410J.grader.scoring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Author: Susham Kumar
*/

public class ProjectSubmissionOutputFileParser {
public ProjectSubmissionOutputFileParser(Reader source) {

private final BufferedReader bufferedReader;
private static final String SUBMITTEDBY="Submitted by";
private static final String SUBMITTEDON="Submitted on";
private static final String GRADEDON="Graded on";


public ProjectSubmissionOutputFileParser(Reader source) {
if(source != null) {
bufferedReader = new BufferedReader(source);
}
else
throw new NullPointerException();

}

public ProjectSubmission parse() {
throw new UnsupportedOperationException("Not implemented yet");
public ProjectSubmission parse() throws ParseException, IOException, InvalidFileContentException {

projectSubmission = new ProjectSubmission();
String fileContents=null;


while((fileContents= bufferedReader.readLine()) !=null) {
fileContents=fileContents.trim();
if(fileContents.contains("CS410J")){ // fileContents has the student Id and Project Name.
String[] splitContent=fileContents.split(Pattern.quote("."));
projectSubmission.setProjectName(splitContent[splitContent.length -1]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the output file being parsed is bogus, we'll end up with ArrayIndexOutOfBoundsExceptions, but I don't know what we could do about it. Maybe an answer will be become apparent later as we build more of the class..

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, bogus output file is always going to be an issue. probably I can write a test case to handle the bogus output file.

As of the first iteration, handling this scenario should help to move on. But, we need to find out a better way or use a different type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed.

projectSubmission.setStudentId(splitContent[splitContent.length -2]);

}

if(fileContents.contains(SUBMITTEDBY)){ //fileContents has StudentName
String [] splitContent=fileContents.split(SUBMITTEDBY);
projectSubmission.setStudentName(splitContent[splitContent.length -1].trim());
}

if(fileContents.contains(SUBMITTEDON)){ //fileContents has Submission Time
String [] splitContent=fileContents.split(SUBMITTEDON);
projectSubmission.setSubmissionTime(parseSubmissionTime(splitContent[splitContent.length -1].trim()));

}

if(fileContents.contains(GRADEDON)){ //fileContents has Graded Time
String [] splitContent=fileContents.split(GRADEDON);
projectSubmission.setGradedTime(parseGradingTime(splitContent[splitContent.length -1].trim()));
}

if(fileContents.contains("out of")){ //fileContents has Total Points and Awarded Points

Pattern rightpattern = Pattern.compile("(?<=out of).*");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought there was a way to go this with a single regular expression. But maybe not.

Pattern leftpattern=Pattern.compile(".*(?=out of)");
Matcher rightmatcher = rightpattern.matcher(fileContents);
Matcher leftmatcher = leftpattern.matcher(fileContents);
if (rightmatcher.find()) {
projectSubmission.setTotalPoints(Double.parseDouble(rightmatcher.group().trim()));
}
else
{
throw new InvalidFileContentException("Not able to retrieve Total Points");
}
if(leftmatcher.find()){

projectSubmission.setScore(Double.parseDouble(leftmatcher.group().trim()));
}
else {
throw new InvalidFileContentException("Not able to retrieve the Score");
}
}
}
return projectSubmission;
}

public static Date parseSubmissionTime(String submissionTimeString) {
return null;
public static Date parseSubmissionTime(String submissionTimeString) throws ParseException {

DateFormat format = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
Date date = format.parse(submissionTimeString);

return date;
}

public static Date parseGradingTime(String gradingTimeString) {
return null;
public static Date parseGradingTime(String gradingTimeString) throws ParseException {
DateFormat gradingTimeFormat = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy");
String test= gradingTimeFormat.format(new Date());
Date date = gradingTimeFormat.parse(gradingTimeString);

return date;
}


private ProjectSubmission projectSubmission;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,70 +9,71 @@
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ProjectSubmissionXmlConverter {
private final JAXBContext xmlContext;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final JAXBContext xmlContext;
private final Logger logger = LoggerFactory.getLogger(this.getClass());

public ProjectSubmissionXmlConverter() throws JAXBException {
xmlContext = JAXBContext.newInstance(ProjectSubmission.class);
}
public ProjectSubmissionXmlConverter() throws JAXBException {
xmlContext = JAXBContext.newInstance(ProjectSubmission.class);
}

public void convertToXml(ProjectSubmission submission, Writer writer) throws JAXBException {
Marshaller marshaller = this.xmlContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(submission, writer);
}
public void convertToXml(ProjectSubmission submission, Writer writer) throws JAXBException {
Marshaller marshaller = this.xmlContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(submission, writer);
}

public ProjectSubmission convertFromXml(Reader reader) throws JAXBException {
Unmarshaller unmarshaller = this.xmlContext.createUnmarshaller();
return (ProjectSubmission) unmarshaller.unmarshal(reader);
}
public ProjectSubmission convertFromXml(Reader reader) throws JAXBException {
Unmarshaller unmarshaller = this.xmlContext.createUnmarshaller();
return (ProjectSubmission) unmarshaller.unmarshal(reader);
}

public static void main(String... args) throws JAXBException {
List<String> outFileNames = new ArrayList<>();
outFileNames.addAll(Arrays.asList(args));
public static void main(String... args) throws JAXBException {
List<String> outFileNames = new ArrayList<>();
outFileNames.addAll(Arrays.asList(args));

if (outFileNames.isEmpty()) {
usage("Missing project submission out file name");
}
if (outFileNames.isEmpty()) {
usage("Missing project submission out file name");
}

ProjectSubmissionXmlConverter converter = new ProjectSubmissionXmlConverter();
outFileNames.stream().map(File::new).forEach(converter::convertOutFileToXml);
}
ProjectSubmissionXmlConverter converter = new ProjectSubmissionXmlConverter();
outFileNames.stream().map(File::new).forEach(converter::convertOutFileToXml);
}

private void convertOutFileToXml(File outFile) {

File xmlFile = null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the only change that you made to this method is to move this variable declaration to the top? If so, I'm not sure if that's necessary. This isn't C where you need to declare all variables at the beginning of a function. In Java, it's preferred to declare variables close to where they are used.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to move the variable declaration to the top, because the variable scope wasn't sufficient. That was because of the try, catch block. I think, I have to refactor the code to make the unit test cases pass.

if (!outFile.exists()) {
logger.error("Output file \"" + outFile + "\" does not exist");
return;
}

ProjectSubmission submission;
try {
ProjectSubmissionOutputFileParser parser = new ProjectSubmissionOutputFileParser(new FileReader(outFile));
submission = parser.parse();

} catch (FileNotFoundException e) {
logger.error("Could not file file " + outFile, e);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked having this specific error message when the file could not be found.

return;
}
ProjectSubmissionOutputFileParser parser = new ProjectSubmissionOutputFileParser(new FileReader(outFile));
ProjectSubmission submission = parser.parse();

String outFileName = outFile.getName();
String filePrefix= outFileName.substring(outFileName.indexOf('.'));
String xmlFileName = filePrefix + ".xml";

File directory = outFile.getParentFile();
File xmlFile = new File(directory, xmlFileName);
xmlFile = new File(directory, xmlFileName);


try {
convertToXml(submission, new FileWriter(xmlFile));

} catch (JAXBException | IOException e) {
}
catch (JAXBException | IOException e) {
logger.error("While writing to " + xmlFile, e);
}
catch (ParseException| InvalidFileContentException e) {
logger.error("Exception" + xmlFile, e);
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.junit.Ignore;
import org.junit.Test;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

Expand All @@ -25,7 +27,6 @@ public class ProjectSubmissionOutputFileParserTest {

*/

@Ignore
@Test
public void parseProjectName() {
OutputFile file = new OutputFile();
Expand All @@ -35,7 +36,6 @@ public void parseProjectName() {
assertThat(submission.getProjectName(), equalTo("Project3"));
}

@Ignore
@Test
public void parseStudentId() {
OutputFile file = new OutputFile();
Expand All @@ -45,7 +45,6 @@ public void parseStudentId() {
assertThat(submission.getStudentId(), equalTo("whitlock"));
}

@Ignore
@Test
public void parseStudentName() {
OutputFile file = new OutputFile();
Expand All @@ -56,9 +55,8 @@ public void parseStudentName() {
assertThat(submission.getStudentName(), equalTo("David Whitlock"));
}

@Ignore
@Test
public void parseSubmissionTime() {
public void parseSubmissionTime() throws ParseException {
OutputFile file = new OutputFile();
String submissionTimeString = "2017-Jul-28 19:51:41";

Expand All @@ -71,9 +69,9 @@ public void parseSubmissionTime() {
assertThat(submission.getSubmissionTime(), equalTo(submissionTime));
}

@Ignore
@Test
public void parseGradingTime() {

public void parseGradingTime() throws ParseException {
OutputFile file = new OutputFile();
String gradingTimeString = "Fri Jul 28 19:53:58 PDT 2017";

Expand All @@ -84,10 +82,10 @@ public void parseGradingTime() {

ProjectSubmission submission = parse(file);
Date gradingTime = ProjectSubmissionOutputFileParser.parseGradingTime(gradingTimeString);
assertThat(submission.getSubmissionTime(), equalTo(gradingTime));
assertThat(submission.getGradedTime(), equalTo(gradingTime));
}

@Ignore

@Test
public void parseTotalPoints() {
OutputFile file = new OutputFile();
Expand All @@ -103,7 +101,7 @@ public void parseTotalPoints() {
assertThat(submission.getTotalPoints(), equalTo(8.0));
}

@Ignore

@Test
public void parseEmptyGrade() {
OutputFile file = new OutputFile();
Expand All @@ -119,7 +117,7 @@ public void parseEmptyGrade() {
assertThat(submission.getScore(), equalTo(null));
}

@Ignore

@Test
public void parseSpecifiedGrade() {
OutputFile file = new OutputFile();
Expand Down Expand Up @@ -185,7 +183,10 @@ public void parseCompilerTestWithNoOutput() {
file.line();
file.line("***** Test 1: No arguments");

ProjectSubmission submission = parse(file);
ProjectSubmission submission = null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think that splitting the declaration and assignment make the code easier to read? I'm not so sure.


submission = parse(file);

List<TestCaseOutput> testCases = submission.getTestCaseOutputs();
assertThat(testCases.size(), equalTo(2));

Expand All @@ -198,7 +199,7 @@ public void parseCompilerTestWithNoOutput() {

@Ignore
@Test
public void parseTest1() {
public void parseTest1() throws IOException, ParseException {
OutputFile file = new OutputFile();
String testName = "Test 1";
String description = "No arguments";
Expand Down Expand Up @@ -234,9 +235,21 @@ public void parseTest1() {


private ProjectSubmission parse(OutputFile file) {
ProjectSubmission projectSubmission = null;
try {
String text = file.getText();
ProjectSubmissionOutputFileParser parser = new ProjectSubmissionOutputFileParser(new StringReader(text));
return parser.parse();
projectSubmission= parser.parse();

parser.parse();
} catch (ParseException e) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might as well have the parse() method declare that it should throw the ParseException.

e.printStackTrace();
} catch (IOException e) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this is what you want to do. Yes, the stack trace will be printed, but null will be returned from the method. That will probably cause the test to fail, but perhaps not in the way that anyone would expect.

e.printStackTrace();
} catch (InvalidFileContentException e) {
e.printStackTrace();
}
return projectSubmission;
}

private class OutputFile {
Expand Down