Skip to content

Commit 40cdc41

Browse files
author
dengzi
committed
FileTree abs
1 parent be8de8c commit 40cdc41

2 files changed

Lines changed: 171 additions & 109 deletions

File tree

src/com/dengzii/plugin/auc/FileTree.kt

Lines changed: 0 additions & 109 deletions
This file was deleted.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package com.dengzii.plugin.auc
2+
3+
import com.dengzii.plugin.auc.template.AucTemplate
4+
import com.dengzii.plugin.auc.template.Placeholder
5+
import com.dengzii.plugin.auc.template.replacePlaceholder
6+
import java.io.File
7+
8+
/**
9+
* <pre>
10+
* author : dengzi
11+
* e-mail : denua@foxmail.com
12+
* github : https://github.com/dengzii
13+
* time : 2019/1/1
14+
* desc :
15+
</pre> */
16+
open class FileTreeNode private constructor() {
17+
18+
var name: String
19+
get() = realName.replacePlaceholder(placeHolderMap)
20+
set(value) {
21+
realName = value
22+
}
23+
24+
var isDir = true
25+
val children by lazy { mutableListOf<FileTreeNode>() }
26+
var placeHolderMap: MutableMap<Placeholder, String>? = null
27+
get() = field ?: parent?.placeHolderMap
28+
29+
// the origin name with original placeholder
30+
private var realName: String = ""
31+
private var parent: FileTreeNode? = null
32+
33+
34+
companion object {
35+
private val TAG = FileTreeNode::class.java.simpleName
36+
37+
fun root(path: String): FileTreeNode {
38+
val root = File(path)
39+
if (!root.isDirectory) {
40+
throw RuntimeException("The root must be a directory.")
41+
}
42+
return with(FileTreeNode(null, path, true)) {
43+
this.parent = this
44+
this
45+
}
46+
}
47+
}
48+
49+
constructor(block: FileTreeNode.() -> Unit) : this() {
50+
invoke(block)
51+
}
52+
53+
constructor(parent: FileTreeNode?, name: String, isDir: Boolean) : this() {
54+
this.name = name
55+
this.parent = parent
56+
this.isDir = isDir
57+
}
58+
59+
operator fun invoke(block: FileTreeNode.() -> Unit): FileTreeNode {
60+
this.block()
61+
return this
62+
}
63+
64+
/**
65+
* set current node as root.
66+
* the file of specified path must be a directory and exist.
67+
* the root's 'name' is the root path of entire file tree.
68+
*
69+
* @param path: The root directory path of whole file tree
70+
*/
71+
fun setRoot(path: String): FileTreeNode {
72+
if (!File(path).isDirectory) {
73+
throw RuntimeException("The root must be a directory.")
74+
}
75+
parent = this
76+
name = path
77+
return this
78+
}
79+
80+
/**
81+
* traversal and create file tree, must be called from the root node.
82+
* the existing files will be skipped
83+
*/
84+
fun create() {
85+
if (!isRoot()) {
86+
throw RuntimeException("Must create structure from root node.")
87+
}
88+
createChild()
89+
}
90+
91+
/**
92+
* traverse and call back each node of the entire file tree.
93+
*/
94+
fun traversal(block: (it: FileTreeNode, depth: Int) -> Unit, depth: Int = 0) {
95+
if (!isDir) return
96+
97+
children.forEach {
98+
block(it, depth)
99+
it.traversal(block, depth + 1)
100+
}
101+
}
102+
103+
/**
104+
* merge all children of another node to 'this.children'.
105+
*/
106+
fun include(other: FileTreeNode) {
107+
if (!isDir) return
108+
children.addAll(other.children)
109+
}
110+
111+
fun dir(name: String, block: FileTreeNode.() -> Unit = {}) {
112+
if (!isDir) return
113+
val dir = FileTreeNode(this, name, true)
114+
children.add(dir)
115+
dir(block)
116+
}
117+
118+
fun file(name: String) {
119+
if (!isDir) return
120+
children.add(FileTreeNode(this, name, false))
121+
}
122+
123+
/**
124+
* get path of current node.
125+
* if the current node is the root node, it will return absolute path,
126+
* otherwise return relative path.
127+
*/
128+
fun getPath(): String {
129+
if (isRoot() || parent == null || parent!!.name == "") {
130+
return name
131+
}
132+
return parent!!.getPath() + "/" + name
133+
}
134+
135+
136+
fun isRoot(): Boolean {
137+
return this == parent
138+
}
139+
140+
fun getTreeGraph(): String {
141+
val strBuilder = StringBuilder()
142+
traversal({ i, dep ->
143+
val head = if (i.isRoot()) "" else if (children.last() == i) "" else ""
144+
strBuilder.append("".repeat(dep) + "$head" + i.name)
145+
})
146+
return strBuilder.toString()
147+
}
148+
149+
private fun createChild() {
150+
children.forEach {
151+
val file = File(it.getPath())
152+
if (file.exists()) {
153+
Logger.d(TAG, "${file.absolutePath} already exists.")
154+
} else {
155+
Logger.d(TAG, "create ${file.absolutePath}")
156+
if (it.isDir) {
157+
file.mkdir()
158+
} else {
159+
file.createNewFile()
160+
}
161+
}
162+
if (it.isDir) {
163+
it.createChild()
164+
}
165+
}
166+
}
167+
168+
override fun toString(): String {
169+
return "FileTreeNode(path='${getPath()}')"
170+
}
171+
}

0 commit comments

Comments
 (0)