@@ -44,11 +44,14 @@ open class FileTreeNode() {
4444 @Transient
4545 var parent: FileTreeNode ? = null
4646
47+ @Transient
48+ private var module: Module ? = null
49+
4750 companion object {
4851
49- var packageNameToDirs = true
5052 private val TAG = FileTreeNode ::class .java.simpleName
51- private val sPathSplitPattern = Pattern .compile(" [./]" )
53+ private val sPathSplitPattern = Pattern .compile(" [/]" )
54+ private val sPkgSplitPattern = Pattern .compile(" [\\ .]" )
5255 private val sPlaceholderPattern = Pattern .compile(" \\ $\\ {([A-Za-z0-9_\\ -]+)}" )
5356
5457 fun root (path : String ): FileTreeNode {
@@ -69,6 +72,16 @@ open class FileTreeNode() {
6972 this .isDir = isDir
7073 }
7174
75+ fun init (module : Module ) {
76+ this .module = module
77+ children.forEach {
78+ it.parent = this
79+ if (it.isDir) {
80+ it.init (module)
81+ }
82+ }
83+ }
84+
7285 fun getTreeNodeCount (): Int {
7386 var count = realChildren.size
7487 realChildren.forEach {
@@ -134,9 +147,11 @@ open class FileTreeNode() {
134147
135148 private fun getRealName (fileName : String = this.name): String {
136149 return if (isDir) {
137- fileName.replacePlaceholder(getPlaceholderInherit(), false ).toLowerCase()
150+ val rn = fileName.replacePlaceholder(getPlaceholderInherit(), false )
151+ if (getModuleInherit()?.lowercaseDir == true ) rn.lowercase() else rn
138152 } else {
139- fileName.replacePlaceholder(getPlaceholderInherit(), true )
153+ val capitalize = getModuleInherit()?.capitalizeFile ? : false
154+ fileName.replacePlaceholder(getPlaceholderInherit(), capitalize)
140155 }
141156 }
142157
@@ -315,30 +330,50 @@ open class FileTreeNode() {
315330 }
316331
317332 /* *
318- * build file tree
319- * replace placeholder in name
320- * if this is directory and name is a path or package name
321- * the name will expand to several dirs
333+ * expand path name to dir structure
322334 */
323- fun build () {
324-
335+ fun expandPath () {
325336 if (! isDir) {
326337 return
327338 }
328- name = getRealName()
329339 if (! isRoot()) {
330- val dir = if (packageNameToDirs) {
331- name.split(sPathSplitPattern)
332- } else {
333- name.split(" /" )
334- }.filter {
335- it.isNotBlank()
336- }.toMutableList()
340+ val dir = name.split(" /" )
341+ .filter {
342+ it.isNotBlank()
343+ }
344+ .toMutableList()
345+ expandDirs(dir)
346+ }
347+ realChildren.forEach {
348+ it.expandPath()
349+ }
350+ }
337351
352+ /* *
353+ * expand the package name to dir structure, eg: `com.example.app` to `com/example/app`
354+ */
355+ fun expandPkgName (replacePlaceholder : Boolean = true) {
356+ if (! isDir) {
357+ return
358+ }
359+ val pkgName2Dir = getModuleInherit()?.packageNameToDir ? : false
360+ if (! pkgName2Dir) {
361+ return
362+ }
363+ if (replacePlaceholder) {
364+ name = getRealName()
365+ }
366+ if (! isRoot()) {
367+ val dir = name
368+ .split(sPkgSplitPattern)
369+ .filter {
370+ it.isNotBlank()
371+ }
372+ .toMutableList()
338373 expandDirs(dir)
339374 }
340375 realChildren.forEach {
341- it.build( )
376+ it.expandPkgName(replacePlaceholder )
342377 }
343378 }
344379
@@ -403,6 +438,7 @@ open class FileTreeNode() {
403438 val clone = FileTreeNode (null , name, isDir)
404439 clone.fileTemplates = fileTemplates?.toMutableMap()
405440 clone.placeholders = placeholders?.toMutableMap()
441+ clone.module = module
406442 realChildren.forEach {
407443 clone.addChild(it.clone())
408444 }
@@ -422,28 +458,32 @@ open class FileTreeNode() {
422458 head.forEach {
423459 str.append(it)
424460 }
425- str.append(when (this ) {
426- parent?.realChildren?.last() -> " └─"
427- parent?.realChildren?.first() -> " ├─"
428- else -> {
429- when {
430- parent != null -> " ├─"
431- else -> " "
461+ str.append(
462+ when (this ) {
463+ parent?.realChildren?.last() -> " └─"
464+ parent?.realChildren?.first() -> " ├─"
465+ else -> {
466+ when {
467+ parent != null -> " ├─"
468+ else -> " "
469+ }
432470 }
433471 }
434- } )
472+ )
435473 str.append(getRealName())
436474 if (isDir) {
437475// str.append("\tplaceholder: ").append(placeholders)
438476 }
439477 str.append(" \n " )
440478
441479 if (! realChildren.isNullOrEmpty()) {
442- head.push(when {
443- parent == null -> " "
444- parent?.realChildren?.last() != this -> " │\t "
445- else -> " \t "
446- })
480+ head.push(
481+ when {
482+ parent == null -> " "
483+ parent?.realChildren?.last() != this -> " │\t "
484+ else -> " \t "
485+ }
486+ )
447487 realChildren.forEach {
448488 str.append(it.getNodeGraph(head))
449489 }
@@ -471,6 +511,10 @@ open class FileTreeNode() {
471511 }
472512 }
473513
514+ private fun getModuleInherit (): Module ? {
515+ return module ? : parent?.getModuleInherit()
516+ }
517+
474518 private fun getLabel (): String {
475519 return " ${name} _$isDir "
476520 }
@@ -498,13 +542,23 @@ open class FileTreeNode() {
498542 return this
499543 }
500544 placeholders.forEach { (k, v) ->
501- val replaced = if (capitalize) {
502- v.toLowerCase().capitalize()
503- } else {
504- v
545+ var replacement = v
546+ if (capitalize) {
547+ replacement = v.lowercase(Locale .getDefault())
548+ .replaceFirstChar {
549+ if (it.isLowerCase()) {
550+ it.titlecase(Locale .getDefault())
551+ } else {
552+ it.toString()
553+ }
554+ }
505555 }
506- after = after.replace(" \$ {$k }" , replaced)
556+ after = after.replace(" \$ {$k }" , replacement)
557+ }
558+ return if (after == this || ! after.contains(' $' )) {
559+ after
560+ } else {
561+ after.replacePlaceholder(placeholders, capitalize)
507562 }
508- return after
509563 }
510564}
0 commit comments