
com.felipebz.flr.internal.toolkit.ToolkitPresenter.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zpa-toolkit Show documentation
Show all versions of zpa-toolkit Show documentation
Z PL/SQL Analyzer :: SSLR Toolkit
The newest version!
/**
* Z PL/SQL Analyzer
* Copyright (C) 2015-2024 Felipe Zorzo
* mailto:felipe AT felipezorzo DOT com DOT br
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.felipebz.flr.internal.toolkit
import com.felipebz.flr.api.AstNode
import com.felipebz.flr.api.RecognitionException
import com.felipebz.flr.api.Trivia
import com.felipebz.flr.toolkit.ConfigurationModel
import com.felipebz.flr.toolkit.ConfigurationProperty
import com.felipebz.flr.xpath.api.AstNodeXPathQuery.Companion.create
import java.awt.Point
import java.io.IOException
import java.io.PrintWriter
import java.io.StringWriter
import java.io.Writer
import java.lang.Thread.UncaughtExceptionHandler
import java.nio.file.Files
import java.nio.file.Paths
internal class ToolkitPresenter(private val configurationModel: ConfigurationModel, private val model: SourceCodeModel) {
private lateinit var view: ToolkitView
fun setView(view: ToolkitView) {
this.view = view
}
fun checkInitialized() {
check(::view.isInitialized) { "the view must be set before the presenter can be ran" }
}
fun initUncaughtExceptionsHandler() {
Thread.currentThread().uncaughtExceptionHandler = UncaughtExceptionHandler { _, e ->
val result: Writer = StringWriter()
val printWriter = PrintWriter(result)
if (e is RecognitionException) {
printWriter.append(e.message)
} else {
e.printStackTrace(printWriter)
}
view.appendToConsole(result.toString())
view.setFocusOnConsoleView()
}
}
fun initConfigurationTab() {
for (configurationProperty in configurationModel.properties) {
view.addConfigurationProperty(configurationProperty.name, configurationProperty.description)
view.setConfigurationPropertyValue(configurationProperty.name, configurationProperty.value)
}
}
fun run(title: String?) {
checkInitialized()
initUncaughtExceptionsHandler()
view.setTitle(title)
view.displaySourceCode("", emptyList())
view.displayAst(null)
view.displayXml("")
view.displayScope(null)
view.displayStatistics(0, 0, 0, 0)
view.disableXPathEvaluateButton()
initConfigurationTab()
view.run()
}
fun onSourceCodeOpenButtonClick() {
val fileToParse = view.pickFileToParse()
if (fileToParse != null) {
view.clearConsole()
try {
view.displaySourceCode(
String(Files.readAllBytes(Paths.get(fileToParse.path)), configurationModel.charset), emptyList())
} catch (e: IOException) {
throw RuntimeException(e)
}
model.setSourceCode(fileToParse, configurationModel.charset)
val symbolTable = model.symbolTable
view.displaySourceCode(model.sourceCode, model.astNode.tokens)
view.displayAst(model.astNode)
view.displayXml(model.xml)
view.displayScope(symbolTable.scopes.firstOrNull())
view.displayStatistics(model.sourceCode.length, model.astNode.lastTokenOrNull?.endLine, model.astNode.tokens.size, model.parseTime)
view.scrollSourceCodeTo(Point(0, 0))
view.setFocusOnAbstractSyntaxTreeView()
view.enableXPathEvaluateButton()
}
}
fun onSourceCodeParseButtonClick() {
view.clearConsole()
val sourceCode = view.sourceCode
model.setSourceCode(sourceCode)
val symbolTable = model.symbolTable
val sourceCodeScrollbarPosition = view.sourceCodeScrollbarPosition
view.displaySourceCode(model.sourceCode, model.astNode.tokens)
view.displayAst(model.astNode)
view.displayXml(model.xml)
view.displayScope(symbolTable.scopes.firstOrNull())
view.displayStatistics(model.sourceCode.length, model.astNode.lastTokenOrNull?.endLine, model.astNode.tokens.size, model.parseTime)
view.scrollSourceCodeTo(sourceCodeScrollbarPosition)
view.setFocusOnAbstractSyntaxTreeView()
view.enableXPathEvaluateButton()
}
fun onXPathEvaluateButtonClick() {
val xpath = view.xPath ?: return
val xpathQuery = create(xpath)
view.clearConsole()
view.clearAstSelections()
view.clearSourceCodeHighlights()
var firstAstNode: AstNode? = null
for (resultObject in xpathQuery.selectNodes(model.astNode)) {
if (resultObject is AstNode) {
if (firstAstNode == null) {
firstAstNode = resultObject
}
view.selectAstNode(resultObject)
if (resultObject.hasToken()) {
view.highlightSourceCode(resultObject.token, resultObject.lastToken)
}
}
}
view.scrollAstTo(firstAstNode)
view.scrollSourceCodeTo(firstAstNode?.tokenOrNull)
view.setFocusOnAbstractSyntaxTreeView()
}
fun onSourceCodeKeyTyped() {
view.displayAst(null)
view.displayXml("")
view.displayScope(null)
view.displayStatistics(0, 0, 0, 0)
view.clearSourceCodeHighlights()
view.disableXPathEvaluateButton()
}
fun onSourceCodeTextCursorMoved() {
view.clearAstSelections()
val astNode = view.astNodeFollowingCurrentSourceCodeTextCursorPosition
view.selectAstNode(astNode)
view.scrollAstTo(astNode)
}
fun onAstSelectionChanged() {
view.clearSourceCodeHighlights()
var firstAstNode: AstNode? = null
for (astNode in view.selectedAstNodes) {
if (firstAstNode == null) {
firstAstNode = astNode
}
if (astNode.hasToken()) {
view.highlightSourceCode(astNode.token, astNode.lastToken)
}
}
var firstTrivia: Trivia? = null
for (trivia in view.selectedTrivias) {
if (firstTrivia == null) {
firstTrivia = trivia
}
view.highlightSourceCode(trivia.token, trivia.tokens.last())
}
if (firstAstNode != null) {
view.scrollSourceCodeTo(firstAstNode.tokenOrNull)
} else {
view.scrollSourceCodeTo(firstTrivia?.token)
}
}
fun onSymbolSelectionChanged() {
view.clearSourceCodeHighlights()
var firstAstNode: AstNode? = null
for (astNode in view.selectedSymbolOrScopeTrees) {
if (firstAstNode == null) {
firstAstNode = astNode
}
view.highlightSourceCode(astNode.token, astNode.lastToken)
}
view.scrollSourceCodeTo(firstAstNode?.tokenOrNull)
}
fun onConfigurationPropertyFocusLost(name: String) {
val configurationProperty = requireNotNull(getConfigurationPropertyByName(name)) {
"No such configuration property: $name"
}
val newValueCandidate = checkNotNull(view.getConfigurationPropertyValue(name))
val errorMessage = configurationProperty.validate(newValueCandidate)
view.setConfigurationPropertyErrorMessage(configurationProperty.name, errorMessage)
if ("" == errorMessage) {
configurationProperty.value = newValueCandidate
configurationModel.setUpdatedFlag()
} else {
view.setFocusOnConfigurationPropertyField(name)
view.setFocusOnConfigurationView()
}
}
private fun getConfigurationPropertyByName(name: String): ConfigurationProperty? {
for (configurationProperty in configurationModel.properties) {
if (name == configurationProperty.name) {
return configurationProperty
}
}
return null
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy