Skip to main content

Architecture overview

Openflexo is a stack of components, each in its own repository, built one on top of the other. This page gives the map; the repository map lists every repository, and Component versions says which versions go together.

The layers

Layering is strict, bottom-up: a lower layer never depends on a higher one.

LayerRepositoriesWhat it provides
Buildopenflexo-buildpluginthe Gradle plugins every repository builds with, and the version of every component
Foundationsconniethe expression language and the bindings (connie-core, the default and Java expression languages and their parsers)
pamelathe modeling framework: annotated interfaces turned into stateful model objects (pamela-core, pamela-security-patterns)
openflexo-utilsutility classes shared by the layers above
gina, dianathe framework for user interfaces (widgets, the .fib components and inspectors) and the framework for diagrams and 2D drawing
Coreopenflexo-corethe federation engine and the FML language: flexo-foundation (resources, resource centers and the FML runtime model), fml-parser (the FML grammar), fml-cli (the command interpreter), fml-lsp, the ontology support
User interfaceopenflexo-uithe shared user interface of the applications, built on Gina and Diana
Technology adaptersopenflexo-xml, openflexo-emf, openflexo-xlsx, …one repository per kind of resource
Serveropenflexo-serverthe HTTP server and its REST API
Applicationsopenflexo-modeller, free-modelling-editor, enterprise-architecture-editor, modelersthe applications users run
Packagingopenflexo-packagingassembles applications and adapters into the downloadable packages

openflexo-integration-tests sits beside the stack: regression tests and complete use cases that exercise it from the outside.

The rules that hold it together

  • No dependency goes up. connie and pamela know nothing of openflexo-core; the core knows nothing of a technology adapter.
  • A technology adapter never depends on another one. It depends on the core and below. Code useful to several adapters belongs in the core or in a shared library, not in one of them.
  • Model objects are PAMELA interfaces, not plain classes. A model type is an interface annotated @ModelEntity, whose state is declared with @Getter and @Setter and whose behaviour lives in default methods or an @Implementation class. PAMELA supplies the storage, the notifications, the cloning and the validation: a field added to an implementation class is neither persisted nor notified. This is the most common surprise for a newcomer.
  • Model data is reached through Connie bindings, where the surrounding code does so. Calling getters by hand around them breaks FML evaluation and change propagation.
  • The FML syntax is defined in one grammar, fml-parser/src/main/sablecc/fml.sablecc. Parsers are generated from it, never edited (see Build and test). The command interpreter has its own, separate grammar.
  • Resource centers are identified by their base URI, which must be unique on the classpath. A jar declares its resource center in META-INF/resourceCenters/org.openflexo.foundation.resource.FlexoResourceCenter; when two share a URI, the second is silently skipped, with no error.

From a file to a running model

The layers meet at run time as follows. A resource center makes resources visible. A technology adapter knows one kind of resource and offers model slots to reach it. An FML virtual model declares those slots and the concepts built on them, and executing it creates a virtual model instance. The vocabulary defines each of these terms.

Where to look for what

To…Look in
change the FML syntaxopenflexo-core/fml-parser (the grammar, then the hand-written factories that walk the new nodes)
add or change a base model entityopenflexo-core/flexo-foundation
support a new kind of resourcea new technology adapter, see Write a technology adapter
change a screenthe .fib and .inspector files of the module concerned, built on gina
change what a package containsopenflexo-packaging
bump the version of a componentthe buildconfig of openflexo-buildplugin, nowhere else