diff --git a/src/main/java/de/vanitasvitae/imi/codes/persistence/FileRepository.java b/src/main/java/de/vanitasvitae/imi/codes/persistence/FileRepository.java
index 982693e..e0dc588 100644
--- a/src/main/java/de/vanitasvitae/imi/codes/persistence/FileRepository.java
+++ b/src/main/java/de/vanitasvitae/imi/codes/persistence/FileRepository.java
@@ -12,6 +12,16 @@ import java.util.HashMap;
import de.vanitasvitae.imi.codes.input.InvalidOptionException;
import de.vanitasvitae.imi.codes.types.StudyNumber;
+/**
+ * Repository, that stores generated sample codes per study to files on disk.
+ * The repository stores the next sample code which would be generated for any {@link StudyNumber} {@code stn} to
+ * the directory {@code /stn}.
+ * If no sample number record has been found for a {@link StudyNumber}, 0 is returned.
+ *
+ * Additionally, the repository is initialized with some hard-coded values for studies "AAA" and "BBB".
+ * If the user tries to generate codes for those studies, the generated codes start at the hard coded values instead
+ * of 0.
+ */
public class FileRepository {
private final File base;
@@ -30,10 +40,20 @@ public class FileRepository {
hardCoded.put(new StudyNumber("AAA"), 35);
hardCoded.put(new StudyNumber("BBB"), 42);
} catch (InvalidOptionException e) {
+ // It should never happen here, that the hard coded study numbers are invalid.
throw new AssertionError(e);
}
}
+ /**
+ * Return the base directory of the repository.
+ * @return base directory
+ */
+ public File getBaseDirectory() {
+ return base;
+ }
+
+ // Returns a hard coded value, or 0 if absent.
private int getHardCodedOrZero(StudyNumber studyNumber) {
Integer i = hardCoded.get(studyNumber);
return (i != null ? i : 0);
diff --git a/src/test/java/de/vanitasvitae/imi/codes/InputValidatorTest.java b/src/test/java/de/vanitasvitae/imi/codes/input/InputValidatorTest.java
similarity index 99%
rename from src/test/java/de/vanitasvitae/imi/codes/InputValidatorTest.java
rename to src/test/java/de/vanitasvitae/imi/codes/input/InputValidatorTest.java
index 790adfa..3629723 100644
--- a/src/test/java/de/vanitasvitae/imi/codes/InputValidatorTest.java
+++ b/src/test/java/de/vanitasvitae/imi/codes/input/InputValidatorTest.java
@@ -1,4 +1,4 @@
-package de.vanitasvitae.imi.codes;
+package de.vanitasvitae.imi.codes.input;
import static junit.framework.TestCase.assertEquals;
diff --git a/src/test/java/de/vanitasvitae/imi/codes/persistence/FileRepositoryTest.java b/src/test/java/de/vanitasvitae/imi/codes/persistence/FileRepositoryTest.java
new file mode 100644
index 0000000..6e3b4e3
--- /dev/null
+++ b/src/test/java/de/vanitasvitae/imi/codes/persistence/FileRepositoryTest.java
@@ -0,0 +1,90 @@
+package de.vanitasvitae.imi.codes.persistence;
+
+import static junit.framework.TestCase.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Stack;
+
+import de.vanitasvitae.imi.codes.input.InvalidOptionException;
+import de.vanitasvitae.imi.codes.persistence.FileRepository;
+import de.vanitasvitae.imi.codes.types.StudyNumber;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FileRepositoryTest {
+
+ private static FileRepository repository;
+
+ @BeforeClass
+ public static void setup() {
+ // Create a temporary test directory in %TEMP%/imicodes
+ File systemTemp = new File(System.getProperty("java.io.tmpdir"));
+ File tempDir = new File(systemTemp, "imicodes");
+ repository = new FileRepository(tempDir);
+ }
+
+ /**
+ * Test, if the {@link FileRepository} correctly stores and returns values to/from file, and if hard coded values
+ * are respected the first time they are used.
+ *
+ * @throws InvalidOptionException NOT expected.
+ * @throws IOException hopefully NOT expected (the temp dir should be readable)
+ */
+ @Test
+ public void testReadWriteSampleNumbers() throws InvalidOptionException, IOException {
+ StudyNumber studyNumber = new StudyNumber("abc");
+ assertEquals("An unknown study number must return 0 as next sample number",
+ 0, repository.nextSampleCode(studyNumber));
+
+ // The written next sample code must be returned next time
+ int next = 34;
+ repository.writeNextSampleCode(studyNumber, next);
+ assertEquals("The written next sample number must be read next time.",
+ next, repository.nextSampleCode(studyNumber));
+
+ // The FileRepository contains 35 as hard coded sample number for study "AAA".
+
+ StudyNumber hardCoded = new StudyNumber("AAA");
+ assertEquals("The hard coded value must be returned the first time its being read.",
+ 35, repository.nextSampleCode(hardCoded));
+ repository.writeNextSampleCode(hardCoded, 89);
+ assertEquals("If the hard coded value is overwritten, the new value must be read.",
+ 89, repository.nextSampleCode(hardCoded));
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ // Delete the temporary directory which was set up earlier.
+ deleteDirectory(repository.getBaseDirectory());
+ }
+
+ /**
+ * Recursively delete a directory and its contents.
+ *
+ * @param root root directory
+ */
+ private static void deleteDirectory(File root) {
+ if (!root.exists()) {
+ return;
+ }
+ File[] currList;
+ Stack stack = new Stack<>();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ if (stack.lastElement().isDirectory()) {
+ currList = stack.lastElement().listFiles();
+ if (currList != null && currList.length > 0) {
+ for (File curr : currList) {
+ stack.push(curr);
+ }
+ } else {
+ stack.pop().delete();
+ }
+ } else {
+ stack.pop().delete();
+ }
+ }
+ }
+}