Deny cyclic FSFolders (#3)
All checks were successful
Test Workflow / Lint and test library (push) Successful in 3m56s
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:
@@ -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")
|
@@ -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
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user