11package com.lazygeniouz.dfc.file.internals
22
33import android.content.Context
4- import android.database.Cursor
54import android.net.Uri
5+ import android.provider.DocumentsContract
66import android.provider.DocumentsContract.Document.MIME_TYPE_DIR
77import com.lazygeniouz.dfc.file.DocumentFileCompat
8+ import com.lazygeniouz.dfc.resolver.ResolverCompat
89
910/* *
1011 * TreeFileCompat serves as an alternative to the **TreeDocumentFile**
@@ -17,7 +18,7 @@ import com.lazygeniouz.dfc.file.DocumentFileCompat
1718 * Other params same as [DocumentFileCompat].
1819 */
1920internal class TreeDocumentFileCompat constructor(
20- context : Context , documentUri : String , documentName : String = " " , documentSize : Long = 0 ,
21+ context : Context , documentUri : Uri , documentName : String = " " , documentSize : Long = 0 ,
2122 lastModifiedTime : Long = -1L , documentMimeType : String = " " , documentFlags : Int = -1 ,
2223) : DocumentFileCompat(
2324 context, documentUri, documentName, documentSize,
@@ -34,7 +35,7 @@ internal class TreeDocumentFileCompat constructor(
3435 */
3536 override fun createFile (mimeType : String , name : String ): DocumentFileCompat ? {
3637 val treeFileUri = fileController.createFile(mimeType, name)
37- return treeFileUri?.let { fromTreeUri (context, treeFileUri) }
38+ return treeFileUri?.let { make (context, treeFileUri, false ) }
3839 }
3940
4041 /* *
@@ -46,7 +47,7 @@ internal class TreeDocumentFileCompat constructor(
4647 */
4748 override fun createDirectory (name : String ): DocumentFileCompat ? {
4849 val treeFileUri = fileController.createFile(MIME_TYPE_DIR , name)
49- return treeFileUri?.let { fromTreeUri (context, treeFileUri) }
50+ return treeFileUri?.let { make (context, treeFileUri, false ) }
5051 }
5152
5253 /* *
@@ -73,6 +74,17 @@ internal class TreeDocumentFileCompat constructor(
7374 return listFiles().firstOrNull { file -> file.name.isNotEmpty() && file.name == name }
7475 }
7576
77+ /* *
78+ * A [TreeDocumentFileCompat] has a wider range of permissions & hence supports rename.
79+ *
80+ * @return True if the rename was successful, False otherwise.
81+ */
82+ override fun renameTo (name : String ): Boolean {
83+ val newUri = fileController.renameTo(name)
84+ if (newUri != null ) uri = newUri
85+ return newUri != null
86+ }
87+
7688 /* *
7789 * Copy would work only if the underlying Uri is a SingleDocumentFile or a File.
7890 */
@@ -90,25 +102,44 @@ internal class TreeDocumentFileCompat constructor(
90102 internal companion object {
91103
92104 /* *
93- * Extracted in to a separate companion method to not clutter common code while running the
94- * **ContentResolver Queries**.
105+ * Return whether the given [uri] is a tree uri.
95106 */
96- internal fun make (
97- context : Context ,
98- cursor : Cursor , documentUri : Uri ,
99- ): TreeDocumentFileCompat {
100- // cursor.getString(0) is the documentId
101- val documentName: String = cursor.getString(1 )
102- val documentSize: Long = cursor.getLong(2 )
103- val documentLastModified: Long = cursor.getLong(3 )
104- val documentMimeType: String = cursor.getString(4 )
105- val documentFlags: Int = cursor.getLong(5 ).toInt()
106-
107- return TreeDocumentFileCompat (
108- context, documentUri.toString(),
109- documentName, documentSize,
110- documentLastModified, documentMimeType, documentFlags
111- )
107+ private fun isTreeUri (uri : Uri ): Boolean {
108+ val paths = uri.pathSegments
109+ return paths.size >= 2 && " tree" == paths[0 ]
110+ }
111+
112+ /* *
113+ * Build the initial [TreeDocumentFileCompat] from a given [uri].
114+ */
115+ internal fun make (context : Context , uri : Uri , isInitial : Boolean ): TreeDocumentFileCompat ? {
116+ if (! isTreeUri(uri)) {
117+ throw UnsupportedOperationException (" Document Uri is not a Tree uri." )
118+ }
119+
120+ // build a new tree uri if this is a first tree doc creation...
121+ val treeUri = if (isInitial) DocumentsContract .buildDocumentUriUsingTree(
122+ uri, DocumentsContract .getTreeDocumentId(uri)
123+ ) else uri
124+
125+ ResolverCompat .getCursor(context, treeUri, ResolverCompat .fullProjection)
126+ ?.use { cursor ->
127+ if (cursor.moveToFirst()) {
128+ val documentName: String = cursor.getString(1 )
129+ val documentSize: Long = cursor.getLong(2 )
130+ val documentLastModified: Long = cursor.getLong(3 )
131+ val documentMimeType: String = cursor.getString(4 )
132+ val documentFlags: Int = cursor.getLong(5 ).toInt()
133+
134+ return TreeDocumentFileCompat (
135+ context, treeUri,
136+ documentName, documentSize,
137+ documentLastModified, documentMimeType, documentFlags
138+ )
139+ }
140+ }
141+
142+ return null
112143 }
113144 }
114145}
0 commit comments