[Editor] Create ResourceFileNode

This commit is contained in:
2021-03-01 10:59:51 +01:00
parent 965775774c
commit a270414a28
7 changed files with 129 additions and 30 deletions

View File

@@ -59,6 +59,18 @@ task provideGameEngine(type: Copy) {
task provideApi(type: Copy) {
from project(':api').file('src/main/java')
into file('build/resources/main/api')
doLast {
def apiDir = file('build/resources/main/api')
def apiIndex = file('build/resources/main/api.idx')
def buffer = new StringBuilder()
fileTree(apiDir).matching { include "**/*.java" }.each {
buffer.append(apiDir.relativePath(it)).append("\n")
}
apiIndex.write(buffer.toString())
}
}
processResources {

View File

@@ -0,0 +1,21 @@
package com.bartlomiejpluta.base.editor.code.api
import com.bartlomiejpluta.base.editor.file.model.FileNode
import com.bartlomiejpluta.base.editor.file.model.ResourceFileNode
import org.springframework.beans.factory.annotation.Value
import org.springframework.core.io.Resource
import org.springframework.stereotype.Component
import java.io.BufferedReader
@Component
class APIProvider {
@Value("classpath:api.idx")
private lateinit var apiIndex: Resource
val apiNode: FileNode by lazy { loadNode() }
private fun loadNode() = ResourceFileNode.root("api").apply {
apiIndex.inputStream.bufferedReader().use(BufferedReader::readLines).forEach(this::createNode)
}
}

View File

@@ -1,15 +1,16 @@
package com.bartlomiejpluta.base.editor.code.build.compiler
import com.bartlomiejpluta.base.editor.code.api.APIProvider
import com.bartlomiejpluta.base.editor.code.build.exception.BuildException
import com.bartlomiejpluta.base.editor.code.build.model.ClasspathResource
import com.bartlomiejpluta.base.editor.code.build.model.FileNodeResourceAdapter
import com.bartlomiejpluta.base.editor.common.logs.enumeration.Severity
import com.bartlomiejpluta.base.editor.event.AppendBuildLogsEvent
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
import com.bartlomiejpluta.base.editor.file.model.FileType
import org.codehaus.commons.compiler.CompileException
import org.codehaus.commons.compiler.util.resource.FileResource
import org.codehaus.commons.compiler.util.resource.Resource
import org.codehaus.janino.CompilerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import tornadofx.FX.Companion.eventbus
import java.io.File
@@ -18,8 +19,8 @@ import java.io.File
class JaninoCompiler : Compiler {
private val compilerFactory = CompilerFactory()
@Value("classpath:api/**/*.java")
private lateinit var apiFiles: Array<org.springframework.core.io.Resource>
@Autowired
private lateinit var apiProvider: APIProvider
override fun compile(sourceDirectory: FileSystemNode, targetDirectory: File) = try {
tryToCompile(sourceDirectory, targetDirectory)
@@ -56,17 +57,11 @@ class JaninoCompiler : Compiler {
}
private fun prepareCompilationUnits(sourceDirectory: FileSystemNode): Array<Resource> {
val sources = sourceDirectory
.allChildren
.map(FileSystemNode::file)
.filter(File::isFile)
.map(::FileResource)
.toTypedArray<Resource>()
val api = apiFiles
.map(::ClasspathResource)
val sources = sourceDirectory.allChildren
val api = apiProvider.apiNode.allChildren
return (sources + api)
.filter { it.type == FileType.FILE }
.map(::FileNodeResourceAdapter)
.toTypedArray()
return sources + api
}
}

View File

@@ -0,0 +1,10 @@
package com.bartlomiejpluta.base.editor.code.build.model
import com.bartlomiejpluta.base.editor.file.model.FileNode
import org.codehaus.commons.compiler.util.resource.Resource
class FileNodeResourceAdapter(private val fileNode: FileNode) : Resource {
override fun open() = fileNode.inputStream()
override fun getFileName() = fileNode.absolutePath
override fun lastModified() = fileNode.lastModified
}

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.file.model
import javafx.beans.value.ObservableLongValue
import javafx.beans.value.ObservableValue
import java.io.InputStream
import java.io.OutputStream
@@ -19,7 +20,11 @@ interface FileNode {
val parent: FileNode?
val children: Iterable<FileNode>
val allChildren: Iterable<FileNode>
val allChildren: List<FileNode>
get() = children + children.flatMap { it.allChildren }
val lastModifiedProperty: ObservableLongValue
val lastModified: Long
fun delete()
fun rename(name: String)
@@ -29,7 +34,7 @@ interface FileNode {
fun inputStream(): InputStream
fun outputStream(): OutputStream
fun writeBytes(array: ByteArray)
fun writeText(text: String, charset: Charset = Charsets.UTF_8) = writeBytes(text.toByteArray(charset))
fun readText(charset: Charset = Charsets.UTF_8) = inputStream().reader(charset).readText()
fun writeText(text: String, charset: Charset = Charsets.UTF_8) = writeBytes(text.toByteArray(charset))
fun writeBytes(array: ByteArray) = outputStream().use { it.write(array) }
}

View File

@@ -1,12 +1,12 @@
package com.bartlomiejpluta.base.editor.file.model
import javafx.beans.binding.Bindings.createLongBinding
import javafx.beans.binding.Bindings.createStringBinding
import tornadofx.getValue
import tornadofx.observableListOf
import tornadofx.setValue
import tornadofx.toProperty
import java.io.File
import java.io.FileOutputStream
import java.nio.file.Path
class FileSystemNode(file: File, override val parent: FileSystemNode? = null) : FileNode {
@@ -30,8 +30,9 @@ class FileSystemNode(file: File, override val parent: FileSystemNode? = null) :
}
override val children = observableListOf<FileSystemNode>()
override val allChildren: List<FileSystemNode>
get() = children + children.flatMap { it.allChildren }
override val lastModifiedProperty = createLongBinding({ fileProperty.value.lastModified() }, fileProperty)
override val lastModified by lastModifiedProperty
init {
refreshChildren()
@@ -78,7 +79,7 @@ class FileSystemNode(file: File, override val parent: FileSystemNode? = null) :
else -> file.createNewFile()
}
when (val child = findChild(file)) {
when (val child = parent.children.firstOrNull { it.name == file.name }) {
null -> FileSystemNode(file, parent).also { parent.children += it }
else -> child
}
@@ -89,11 +90,5 @@ class FileSystemNode(file: File, override val parent: FileSystemNode? = null) :
override fun outputStream() = file.outputStream()
override fun writeBytes(array: ByteArray): Unit = FileOutputStream(file).use { it.write(array) }
private fun findChild(file: File): FileSystemNode? {
return children.firstOrNull { it.file.name == file.name }
}
fun findByFile(file: File) = allChildren.firstOrNull { it.file.equals(file) }
fun findByFile(file: File) = allChildren.firstOrNull { it.absolutePath == file.absolutePath }
}

View File

@@ -0,0 +1,61 @@
package com.bartlomiejpluta.base.editor.file.model
import javafx.beans.property.StringProperty
import org.springframework.core.io.ClassPathResource
import org.springframework.core.io.Resource
import tornadofx.getValue
import tornadofx.observableListOf
import tornadofx.toProperty
import java.nio.file.Path
class ResourceFileNode private constructor(
private val resource: Resource? = null,
override val parent: ResourceFileNode? = null,
override val type: FileType = FileType.FILE,
name: String? = null
) : FileNode {
override val nameProperty = (resource?.filename ?: name ?: "").toProperty()
override val name by nameProperty
override val extensionProperty = (resource?.filename?.substringAfter(".") ?: "").toProperty()
override val extension by extensionProperty
override val absolutePathProperty: StringProperty =
((parent?.absolutePath ?: "") + "/${nameProperty.value}").toProperty()
override val absolutePath by absolutePathProperty
override val children = observableListOf<ResourceFileNode>()
override val lastModifiedProperty = (resource?.lastModified() ?: 0L).toProperty()
override val lastModified by lastModifiedProperty
override fun createNode(path: String): ResourceFileNode {
val segments = Path.of(path.replace("..", "."))
return segments.foldIndexed(this) { index, parent, segment ->
when (val child = parent.children.firstOrNull { it.name == segment.toString() }) {
null -> when (index < segments.count() - 1) {
true -> directory(segment.toString(), parent)
false -> resource(ClassPathResource("$absolutePath/$path"), parent)
}.also { parent.children += it }
else -> child
}
}
}
override fun inputStream() = resource
?.inputStream
?: throw IllegalStateException("Attempt to open input stream of resource directory")
override fun delete() = throw UnsupportedOperationException()
override fun rename(name: String) = throw UnsupportedOperationException()
override fun refresh() = throw UnsupportedOperationException()
override fun outputStream() = throw UnsupportedOperationException()
companion object {
fun resource(resource: Resource, parent: ResourceFileNode) = ResourceFileNode(resource, parent)
fun directory(name: String, parent: ResourceFileNode) = ResourceFileNode(null, parent, FileType.DIRECTORY, name)
fun root(name: String) = ResourceFileNode(null, null, FileType.DIRECTORY, name)
}
}