Skip to content

Core Concepts

Cydhra edited this page Oct 16, 2022 · 4 revisions

Design Principles

This document describes a few concepts that make up the Acromantula software design. This document is not relevant to users, only to people who want to write code for Acromantula or develop plugins and/or a front-end.

Workspace

Acromantula organizes the entire workflow in a workspace. This workspace consists of a file system abstraction and a database. The workspace is managed by a separate module that hides the file system abstraction and the database specifics and only exposes API endpoints to interact with files in the workspace (Though it does not hide the database completely, because tools and plugins are expected to interact with the database directly). You can find the entire workspace module in the subfolder Workspace at the repository's root.

A new Workspace

Whenever a new workspace is created, Acromantula will create a folder for it, which contains a sub-folder resources, a file for metadata called index and the database file. The resources folder contains every file that is being imported into the database. If archives are imported into the workspace, they are unpacked, and each archive entry is stored separately. This is to reduce access times and ease modification of those files.

File System Abstraction

The application (outside of the workspace module) is never supposed to access those files directly. All interaction with imported files is done via the WorkspaceService facade, which provides all methods required for interaction with those files. Each file is internally abstracted through a FileEntity instance, which is backed by the database and provides access to the file's binary contents through the API.

For example, to create a new empty file in the workspace, you call the method WorkspaceService::addFileEntry(name, parent, content) with a name, an optional FileEntity as its parent directory and an empty ByteArray as its content. The method will return a FileEntity which can be used to address this file in the future.

When a workspace is loaded, the front-end should run the listFiles remote procedure (see workspace.proto) first, which will return a file tree of the current workspace. Analogous, the debug console also has a command ls which will print the current workspace's file tree.

Database

Contrary, the database is not hidden from the application. The workspace module handles creation and population of the database, as well as everything that the file system abstraction stores in the database, but other than that the database is available for the application. Since Exposed is used for database interaction, you can simply address the database using

transaction {
    YourTable.select { YourTable.aColumn eq "foo" }.doSomething()
}

This has one negative side-effect: If a plugin or tool accesses the database while a user changes the active workspace, the plugin or tool will transparently switch to the new database as soon as it starts a new transaction. This will obviously lead to bugs and potentially instable database contents. A solution for this has not been found yet.

Client-Server Architecture

Acromantula does not provide a front-end beyond the debug console. However, it exposes an RPC server based on protobuf files and gRPC on port 26666. This allows a front-end application to interact with the server in a convenient and efficient way, potentially even over a network.

The RPC documentation can be found here

Features

Acromantula defines a set of Features (like Importing, Exporting, Mapping, Viewing, ...). Those features are exposed to the RPC API and thus known and available to the front-end. All features are extensible through interfaces. Plugins are not supposed to add more features, just provide feature extensions (like new importing strategies, exporting strategies, conversion strategies, etc). This way, the GUI and the application know what features exist and how to interact with them, but plugins can provide unique and complex implementations for a wide range of file types.

All features are implemented in a module called Features which can be found in its own folder in the repository. They all have their own facade for interfacing (for example ImporterFeature for importing files), and usually their own protobuf service for interaction with the front-end. Features are not decoupled, so whenever a feature is called, it may call other features to perform some work. For example, when importing a file, the Importer will call the Mapper to generate mappings for the imported file automatically.

Plugins

Acromantula is heavily designed for extensibility. All implementations regarding actual file types are done in plugins. Those plugins register their implementations of different features (see above) at the respective feature facades and optionally register some tables at the database.

More documentation on plugins pending