Fix name conflict resolution for copyDocument

Any documents with the same name existing in a directory that is copied to would cause an exception due to existing already, this fixes that by handling conflict resolution in those cases and automatically determining a file name that would avoid a conflict.
This commit is contained in:
PixelyIon 2022-06-01 21:39:54 +05:30
parent c4bd9c47e4
commit 8efa9298f9

View File

@ -97,12 +97,24 @@ class DocumentsProvider : DocumentsProvider() {
return documentId?.startsWith(parentDocumentId!!) ?: false return documentId?.startsWith(parentDocumentId!!) ?: false
} }
/**
* @return A new [File] with a unique name based off the supplied [name], not conflicting with any existing file
*/
fun File.resolveWithoutConflict(name: String): File {
var file = resolve(name)
if (file.exists()) {
var noConflictId = 1 // Makes sure two files don't have the same name by adding a number to the end
val extension = name.substringAfterLast('.')
val baseName = name.substringBeforeLast('.')
while (file.exists())
file = resolve("$baseName (${noConflictId++}).$extension")
}
return file
}
override fun createDocument(parentDocumentId : String?, mimeType : String?, displayName : String) : String? { override fun createDocument(parentDocumentId : String?, mimeType : String?, displayName : String) : String? {
val parentFile = getFile(parentDocumentId!!) val parentFile = getFile(parentDocumentId!!)
var noConflictId = 1 // Makes sure two files don't have the same name by adding a number to the end val newFile = parentFile.resolveWithoutConflict(displayName)
var newFile = parentFile.resolve(displayName)
while (newFile.exists())
newFile = parentFile.resolve("$displayName (${noConflictId++})")
try { try {
if (DocumentsContract.Document.MIME_TYPE_DIR == mimeType) { if (DocumentsContract.Document.MIME_TYPE_DIR == mimeType) {
@ -129,12 +141,7 @@ class DocumentsProvider : DocumentsProvider() {
val parent = getFile(parentDocumentId!!) val parent = getFile(parentDocumentId!!)
val file = getFile(documentId) val file = getFile(documentId)
var doesFileParentMatch = false if (parent == file || file.parentFile == null || file.parentFile!! == parent) {
val fileParent = file.parentFile
if (fileParent == null || fileParent.equals(parent))
doesFileParentMatch = true
if (parent == file || doesFileParentMatch) {
if (!file.delete()) if (!file.delete())
throw FileNotFoundException("Couldn't delete document with ID '$documentId'") throw FileNotFoundException("Couldn't delete document with ID '$documentId'")
} else { } else {
@ -173,7 +180,8 @@ class DocumentsProvider : DocumentsProvider() {
override fun copyDocument(sourceDocumentId : String, targetParentDocumentId : String?) : String? { override fun copyDocument(sourceDocumentId : String, targetParentDocumentId : String?) : String? {
val parent = getFile(targetParentDocumentId!!) val parent = getFile(targetParentDocumentId!!)
val oldFile = getFile(sourceDocumentId) val oldFile = getFile(sourceDocumentId)
val newFile = parent.resolve(oldFile.name) val newFile = parent.resolveWithoutConflict(oldFile.name)
try { try {
if (!(newFile.createNewFile() && newFile.setWritable(true) && newFile.setReadable(true))) if (!(newFile.createNewFile() && newFile.setWritable(true) && newFile.setReadable(true)))
throw IOException("Couldn't create new file") throw IOException("Couldn't create new file")