Deny cyclic FSFolders (#3)
All checks were successful
Test Workflow / Lint and test library (push) Successful in 3m56s

Contributes to #2 .

Handle cyclic folders explicitly, instead of relying on the filesystem.

Reviewed-on: #3
This commit is contained in:
2024-01-07 14:56:16 +00:00
parent ca221f1907
commit 8aa21dff54
4 changed files with 97 additions and 13 deletions

View File

@@ -1,21 +1,30 @@
package filesystem
import java.nio.file.FileAlreadyExistsException
import java.nio.file.FileSystemException
import java.nio.file.Files
import java.nio.file.Path
class FSCreator {
/**
* Create entry, leaving existing folders' contents, but overwriting existing files.
* @throws CyclicFolderException Cyclic folders cannot be created.
*/
@Throws(FileSystemException::class)
@Throws(CyclicFolderException::class)
fun create(
entryToCreate: FSEntry,
destination: String,
) {
val queue = ArrayDeque<Pair<FSEntry, Path>>()
queue.add(entryToCreate to Path.of(destination))
// No point in running anything if we know the input is invalid.
if (entryToCreate is FSFolder && entryToCreate.isCyclic()) {
throw CyclicFolderException()
}
val queue =
ArrayDeque(
listOf(
entryToCreate to Path.of(destination),
),
)
while (queue.isNotEmpty()) {
val (entry, dest) = queue.removeFirst()
@@ -33,4 +42,6 @@ class FSCreator {
}
}
}
}
}
class CyclicFolderException : Exception("Cyclic FSFolders are not supported")

View File

@@ -6,4 +6,22 @@ sealed class FSEntry(val name: String)
class FSFile(name: String, val content: String) : FSEntry(name)
class FSFolder(name: String, val entries: List<FSEntry>) : FSEntry(name)
class FSFolder(name: String, val entries: List<FSEntry>) : FSEntry(name) {
/**
* Check whether a folder is cyclic.
*/
fun isCyclic(): Boolean {
val seen = listOf(this).toHashSet<FSEntry>()
val queue = ArrayDeque(entries)
while (queue.isNotEmpty()) {
val entry = queue.removeFirst()
if (!seen.add(entry)) {
return true
}
if (entry is FSFolder) {
queue.addAll(entry.entries)
}
}
return false
}
}