Structure101 "modules" are protected scopes - you can define:
- which containers are "modules",
- the public APIs to modules
- the allowed module-to-module dependencies, and
- any deprecated items within the public API's.
If you are using Eclipse, IDEA, Maven or Gradle modules for your project code organization, then you will already see "modules" in your Structure101 model, and you will probably want to keep a 1-to-1 mapping between these and the Structure101 "module" concept, though you are free to deviate if that suits your purposes. You can augment these standard modules by defining the API packages that are visible to other modules. Any reference from outside modules onto code in non-public parts of your module will be considered an "API violation", and can be checked at edit or build time, along with the other Structure101 checks.
This can give you many of the benefits of Java modules, without the overhead of switching your entire build system to Java modules.
Defining Modules and constraining Module-to-Module dependencies
The definition of modules and API's is done through the Studio UI using the actions mechanism in the structure tab - see the "Module" sub-menu on the LSM context menu:
Since the definition of what is a module and what is public is defined using Actions, the corresponding Action list must be selected in order to have an effect (and "shared" for other components, such as Workspace or Build, to use it)
Sharing and importing module specs
Encoding module specs as actions also means that you can import/export these from/to files. This can be done along with the entire Action list (in XML format), or you can import/export just the Module-related actions (in a Tab-Separated Values (TSV) Format). This makes it easy for you to create and import API definitions from 3rd party tools (e.g. UML). The import/export module commands are found on the Action list drop-down menu:
If you are creating a module spec, the TSV file should contain a list of actions, each taking one or two parameters, separated by a <tab>. The commands can be one of:
- set-module
- set-module-interface
- set-deprecated
- add-edge-unchecked
The 3 "set-" commands can take 1 or 2 parameters as follows:
- The fully-qualified name of the node to set - mandatory
- A boolean ("true" or "false") to indicate if the attribute is being set or reset, if omitted this defaults to "true" - optional
The "add-edge-unchecked" command takes 2 parameters:
- The name of the "from" item (module)
- The name of the "to" item (module)
Example:
set-module<tab>a/b/foldername1<tab>true
set-module<tab>a/b/foldername2<tab>true
set-module-interface a/b/foldername1/publicFolder<tab>true
set-deprecated<tab>a/b/foldername1/publicFolder/publicFile.h/void someFunction(unsigned char[], typeName)<tab>true
add-edge-unchecked a/b/foldername1<tab>a/b/foldername2
Notes:
- The names of items must be fully qualified, and must exactly match the path from the root of the Structure101 model.
- The names of methods/functions must include the full signature and this must exactly match the signature in the Structure101 model
Enabling module dependency checking
Once you have started a module/api definition, you can instruct Structure101 to start checking for specific module violations using the project settings.
On your project properties dialog, you will see a "Modules" tab. This lets you select which kinds of module violations you wish to be detected. For example you can define module APIs and have them checked, but not require the module-to-module control (yet).
If "Module API violations" is enabled, then module A can only use the subset of code that is in a "public" region of module B. (Containers can be defined as public using actions on the module sub-menu of the LSM context menu).
Setting "Module requires violations" means that module A can only use any code in module B if there is a direct dependency from the module A node in the LSM onto the module B node. (To add a "requires" dependency, select both module A and module B in the LSM, right-click, add/dependency from A to B).
Setting "Deprecation violations" will cause every dependency onto a deprecated item to be considered a violation. Note that this is in fact independent of the enclosing modules. (The "deprecated" attribute
Once some of these options are selected, the items from which violating dependencies originate are listed on the Structure tab, and you can navigate from this list to investigate the problem/solution in the LSM model.
While you're investigating module violations, you may want to have them highlighted in the LSM - to do this, select the "Always show module violation" on the main toolbar, and any rolled-up dependencies that "carry" violations will be shown as dashed lines:
Public items are shown with a green triangle and deprecated items with a red triangle.
Note:
A specific dependency may violate more than one kind of problem. In this case, it is designated and counted just once.
Counting Module violations
On the summary tab, the total number of Module violations is included in the key measures, with this number broken out to the 3 kinds of Module violations in its own section lower on the page:
The Module violations can be checked by Build, and the violations listed in Workspace and Dashboard so long as the Action list containing the Module definitions is shared and applied.