A core abstraction layer of the COBRA architecture that provides a template implementation of the Interpreter pattern. This framework serves as a foundational design pattern template that can be extended and specialized for various use cases, with AST processing being one of its primary applications.
-
Core Abstraction Layer
- Template implementation of the Interpreter pattern
- Extensible handler and dispatcher interfaces
- Type-safe task and result handling
- Comprehensive licensing mechanism
-
Task Processing Framework
- Thread-safe and concurrent processing
- Dynamic task distribution system
- Flexible handler registration
- Built-in error handling
-
Development Support
- Built-in test utilities and annotations
- Comprehensive documentation
- Example implementations
- Integration guides
- JavaUser: Java 8 or higher
- KotlinUser: Kotlin 1.8 or higher
In your build.gradle.kts:
repositories {
maven { url = uri("https://jitpack.io") }
}dependencies {
implementation("com.github.jhu-seclab-cobra:framework:0.1.0")
}// Simple AST Node interface
interface AstNode {
val nodeType: String
}
// Basic node implementations
data class BinaryExpressionNode(val operator: String) : AstNode {
override val nodeType: String = "BinaryExpression"
}
data class LiteralNode(val value: String) : AstNode {
override val nodeType: String = "Literal"
}
data class VariableNode(val name: String) : AstNode {
override val nodeType: String = "Variable"
}data class AstTask(
override val uid: ITask.ID,
val node: AstNode
) : ITask
data class AstResult(val value: String) : IProduct// Simple workers using SAM pattern
val binaryWorker = IWorker<AstTask, AstResult> { task ->
emit(AstResult("processed_binary"))
}
val literalWorker = IWorker<AstTask, AstResult> { task ->
emit(AstResult("processed_literal"))
}
val variableWorker = IWorker<AstTask, AstResult> { task ->
emit(AstResult("processed_variable"))
}
// Simple dispatcher
class AstDispatcher : IDispatcher<IWorker<AstTask, AstResult>> {
private val workers = mutableMapOf<ITask.ID, IWorker<AstTask, AstResult>>()
override fun dispatch(forTask: ITask.ID) = workers[forTask]
override fun register(forTask: ITask.ID, toWorker: IWorker<AstTask, AstResult>) {
workers[forTask] = toWorker
}
}class AstWorkshop : AbcWorkshop<IWorker<AstTask, AstResult>>() {
@WorkLicense("BinaryExpression")
val binaryWorker = binaryWorker
@WorkLicense("Literal")
val literalWorker = literalWorker
@WorkLicense("Variable")
val variableWorker = variableWorker
}// Create task
val task = AstTask(
uid = ITask.ID("BinaryExpression", setOf("math")),
node = BinaryExpressionNode("+")
)
// Setup framework components
val workshop = AstWorkshop()
val dispatcher = AstDispatcher()
// Register workers
workshop.licensedWorkers().forEach { (taskId, worker) ->
dispatcher.register(taskId, worker)
}
// Process task
val worker = dispatcher.dispatch(task.uid)!!
val result = mutableListOf<AstResult>()
with(worker) {
flow { work(task) }.collect { result.add(it) }
}
println("Result: ${result.first().value}")IWorker<T : ITask, R : IProduct>: Task processing interfaceIDispatcher<W : IWorker<*, *>>: Task distribution interfaceITask: Task definition interfaceIProduct: Result marker interface
AbcWorkshop<W : IWorker<*, *>>: Abstract workshop implementation@WorkLicense: Handler authorization annotation
Run all tests with:
./gradlew testGNU General Public License v2.0
Contributions are welcome! Please open issues or submit pull requests for:
- Bug fixes
- New features
- Documentation improvements
- Test coverage enhancements
Part of the COBRA platform. For more information, see COBRA Project.