88import java .io .IOException ;
99import java .nio .charset .StandardCharsets ;
1010import java .nio .file .InvalidPathException ;
11+ import java .time .LocalDateTime ;
12+ import java .time .format .DateTimeFormatter ;
13+ import java .time .format .DateTimeFormatterBuilder ;
1114import java .util .ArrayList ;
1215import java .util .Enumeration ;
1316import java .util .List ;
17+ import java .util .Optional ;
1418import java .util .regex .Matcher ;
1519import java .util .regex .Pattern ;
1620import java .util .zip .ZipEntry ;
2024public class SolutionParser {
2125
2226 public static final String outputDirectoryPath = "analyser_resources/" ;
23- private final File contentDirectory ;
27+ private final File solutionsDirectory ;
2428 private final File outputDirectory ;
2529 private final boolean preprocessSourceCode ;
2630 private final boolean anonymousResults ;
2731
2832 private final Analyser analyser ;
2933
30- public SolutionParser (File contentDirectory , boolean preprocessSourceCode , boolean anonymousResults , Analyser analyser ) {
31- this .contentDirectory = contentDirectory ;
34+ public SolutionParser (File solutionsDirectory , boolean preprocessSourceCode , boolean anonymousResults , Analyser analyser ) {
35+ this .solutionsDirectory = solutionsDirectory ;
3236 this .outputDirectory = new File (outputDirectoryPath );
3337 System .out .println (outputDirectory .getAbsolutePath ());
3438 this .preprocessSourceCode = preprocessSourceCode ;
@@ -49,11 +53,11 @@ public List<Exercise> parseSolutions() {
4953
5054 // Counts the total number of solutions for progress tracking
5155 try {
52- ZipFile zipFile = new ZipFile (contentDirectory );
56+ ZipFile zipFile = new ZipFile (solutionsDirectory );
5357 Enumeration <? extends ZipEntry > zipEntries = zipFile .entries ();
5458 while (zipEntries .hasMoreElements ()) {
5559 ZipEntry entry = zipEntries .nextElement ();
56- if (!entry .isDirectory ()) {
60+ if (!entry .isDirectory () && entry . getName (). endsWith ( ".py" ) ) {
5761 numSolutions ++;
5862 }
5963 }
@@ -62,41 +66,55 @@ public List<Exercise> parseSolutions() {
6266 }
6367 // File unzipping adapted from: https://www.baeldung.com/java-compress-and-uncompress [11.03.2021]
6468 byte [] buffer = new byte [1024 ];
65- try (ZipInputStream zis = new ZipInputStream (new FileInputStream (contentDirectory ), StandardCharsets .UTF_8 )) {
69+ try (ZipInputStream zis = new ZipInputStream (new FileInputStream (solutionsDirectory ), StandardCharsets .UTF_8 )) {
6670 ZipEntry zipEntry = zis .getNextEntry ();
6771 while (zipEntry != null ) {
6872 File newFile = newFile (outputDirectory , zipEntry );
6973 if (zipEntry .isDirectory ()) {
7074 if (!newFile .isDirectory () && !newFile .mkdirs ()) {
7175 throw new IOException ("Failed to create directory " + newFile );
7276 }
73- } else {
74- // fix for Windows-created archives
75- File parent = newFile .getParentFile ();
76- if (!parent .isDirectory () && !parent .mkdirs ()) {
77- throw new IOException ("Failed to create directory " + parent );
78- }
79- // write file content
80- FileOutputStream fos = new FileOutputStream (newFile );
81- int len ;
82- while ((len = zis .read (buffer )) > 0 ) {
83- fos .write (buffer , 0 , len );
84- }
85- fos .close ();
86- // parse the solution from unzipped file
87- try {
88- Solution solution = parseSolution (newFile );
89- Exercise exercise = exercises .stream ().filter (e -> e .getName ().equals (solution .getExerciseName ())).findAny ().orElse (null );
90- if (exercise != null ) {
91- exercise .addSolution (solution );
92- } else {
93- exercises .add (new Exercise (solution .getExerciseName (), solution ));
77+ }
78+ // If entry is a file
79+ else {
80+ if (zipEntry .getName ().endsWith (".py" )) {
81+ // fix for Windows-created archives
82+ File parent = newFile .getParentFile ();
83+ if (!parent .isDirectory () && !parent .mkdirs ()) {
84+ throw new IOException ("Failed to create directory " + parent );
85+ }
86+ // write file content
87+ FileOutputStream fos = new FileOutputStream (newFile );
88+ int len ;
89+ while ((len = zis .read (buffer )) > 0 ) {
90+ fos .write (buffer , 0 , len );
91+ }
92+ fos .close ();
93+ // parse the solution from unzipped file
94+ try {
95+ Solution newSolution = parseSolution (newFile );
96+ Exercise exercise = exercises .stream ().filter (e -> e .getName ().equals (newSolution .getExerciseName ())).findAny ().orElse (null );
97+ if (exercise != null ) {
98+ Optional <Solution > existingSolution = exercise .getSolutions ().stream ().filter (sol ->
99+ sol .getAuthor ().equals (newSolution .getAuthor ())).findAny ();
100+ // Replace with latest submission of solution if a solution is already present for the author
101+ if (existingSolution .isPresent ()) {
102+ if (existingSolution .get ().getSubmissionTime ().isBefore (newSolution .getSubmissionTime ())) {
103+ System .out .println (newSolution .getAuthor () + " - " + existingSolution .get ().getSubmissionTime () + " - " + newSolution .getSubmissionTime ());
104+ exercise .replaceSolution (exercise .getSolutions ().indexOf (existingSolution .get ()), newSolution );
105+ }
106+ } else {
107+ exercise .addSolution (newSolution );
108+ }
109+ } else {
110+ exercises .add (new Exercise (newSolution .getExerciseName (), newSolution ));
111+ }
112+ } catch (Exception e ) {
113+ e .printStackTrace ();
94114 }
95- } catch ( Exception e ) {
96- e . printStackTrace ( );
115+ parsedSolutions ++;
116+ analyser . updateProcessingProgress ( parsedSolutions , numSolutions );
97117 }
98- parsedSolutions ++;
99- analyser .updateProcessingProgress (parsedSolutions , numSolutions );
100118 }
101119 zipEntry = zis .getNextEntry ();
102120 }
@@ -133,20 +151,24 @@ public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOExce
133151 */
134152 private Solution parseSolution (File sourceCodeFile ) throws Exception {
135153 Solution solution ;
136- Pattern solutionFolderPattern = Pattern .compile ("(.+)_(.+)" );
137- Matcher matcher = solutionFolderPattern .matcher (sourceCodeFile .getParentFile ().getName ());
154+ Pattern authorFolderPattern = Pattern .compile ("(.+ ?) ([0-9]+) (.+)" );
155+ //Pattern solutionFolderPattern = Pattern.compile("(.+)_(.+)");
156+ Matcher matcher = authorFolderPattern .matcher (sourceCodeFile .getParentFile ().getParentFile ().getName ());
138157 if (matcher .find ()) {
139158 String author ;
140159 if (anonymousResults )
141- author = matcher .group (1 );
142- else
143160 author = matcher .group (2 );
144- solution = new Solution (author , sourceCodeFile .getName (), sourceCodeFile );
161+ else
162+ author = matcher .group (1 );
163+ LocalDateTime submissionTime = LocalDateTime .parse (
164+ sourceCodeFile .getParentFile ().getName (),
165+ DateTimeFormatter .ofPattern ("yyyy-MM-dd-HH-mm-ss" ));
166+ solution = new Solution (author , sourceCodeFile .getName (), sourceCodeFile , submissionTime );
145167 } else {
146- throw new InvalidPathException (sourceCodeFile .getParentFile ().getName (), " is an invalid file path. " );
168+ throw new InvalidPathException (sourceCodeFile .getParentFile ().getName (), "Invalid solution file path" );
147169 }
148170 if (preprocessSourceCode ) {
149- preprocessSourceCode2 (sourceCodeFile .getAbsolutePath ());
171+ preprocessSourceCode (sourceCodeFile .getAbsolutePath ());
150172 String sourceCodePath = sourceCodeFile .getAbsolutePath ();
151173 File preProcessedCodeFile = new File (sourceCodePath .substring (0 , sourceCodePath .length () - 3 ) + "_preprocessed.py" );
152174 solution .setPreprocessedCodeFile (preProcessedCodeFile );
@@ -161,7 +183,7 @@ private Solution parseSolution(File sourceCodeFile) throws Exception {
161183 * @param filePath the source code file's path
162184 * @throws Exception if the preprocessing fails
163185 */
164- public void preprocessSourceCode2 (String filePath ) throws Exception {
186+ public void preprocessSourceCode (String filePath ) throws Exception {
165187 final String preprocessorScript = "/ee/ut/similaritydetector/python/Preprocessor.py" ;
166188
167189 PythonInterpreter interpreter = new PythonInterpreter ();
0 commit comments