Skip to content

Latest commit

 

History

History
155 lines (105 loc) · 6.28 KB

concepts.adoc

File metadata and controls

155 lines (105 loc) · 6.28 KB

Concepts

SBM offers commands to scan application source code and run recipes against it. Recipes bundle actions to apply source code migrations or find information in the codebase.

An Action is a single step in a recipe and can be reused by other recipes. Every Recipe has at least one Action and each Recipe and every action has a condition which defines if the recipe and/or it’s actions are applicable.

The condition has access to all resources to evaluate to true or false. If a recipe’s condition evaluates to false the recipe is not displayed. Actions with a condition evaluating to true are applicable and will be executed with the recipe. When all actions of a recipe evaluate to false the recipe itself is not applicable.

Recipes

Recipes can be declared in yaml syntax or provided as Java bean definitions.

Actions

Action is the starting point when developing a recipe. Every Action has access to all resources and their ASTs through the ProjectContext.

class MyAction extends AbstractAction {
    void apply(ProjectContext context) {
        // analyse and modify AST
    }
}

ProjectContext

After scanning and parsing the source code of a given application a ProjectContext gets created. The ProjectContext acts as facade to the abstract syntax tree (AST) of the project and provides an API to access project resources.

ProjectJavaSources pjs = context.getProjectJavaSources();
ApplicationModules am = context.getApplicationModules()

The ProjectContext represents the current application state in memory and provides access to all resources. The API provides methods to retrieve and modify Java source, application modules and build files. All other resource types can be retrieved using finders.

Finders

Finders are useful to access and filter resources.

public interface ProjectResourceFinder<T> {
    T apply(ProjectResourceSet projectResourceSet);
}

Finder have access to the ProjectResourceSet (see [ProjectResourceSet]) to filter/find resources and return the result. The result is of the same type as the generic type T.

The ProjectContext provides a search(..) method to apply Finder.

List<..> resources = projectContext.search(new PathMatchingProjectResourceFinder("/**/some/path/*.file"));

Finders also provide access to specialized resources, resources that are not directly accessible through the ProjectContext Api. Specialized resources like SpringBootApplicationProperties, PersistenceXml, WebXml, …​, can be retrieved by their Finders.

void apply(ProjectContext context) {
    SpringBootApplicationProperties p = context.search(new SpringBootApplicationPropertiesFinder());
    p.getProperty("cloud-profile", "some.property.key")
}

Read the Specialized Resources section to learn how you can provide new Specialized Resources.

Multi module projects

Application Lifecycle

Scan Application

The user provides a root directory to scan a project. After scanning the given directory a set of preconditions is checked to verify that the scanned project can be successfully parsed. See [Check Preconditions] to learn how you can provide additional precondition checks.

Parsing

When all preconditions are met the project resources are parsed and the abstract syntax tree (AST) gets created in memory.

Specialized Resources

After parsing the project resources a set of ProjectResourceWrappers is called and generic resources can be replaced with more specialized resources providing a specialized API for these resources. Think of replacing a generic XML file representing persistence.xml (JPA deployment descriptor) with a specialized resource representation offering an API to act on a specialized "JPA deployment descriptor". See Specialized Resources to learn how yo can provide specialized resources.

Creating the ProjectContext

After replacing specialized resources the ProjectContext gets created.

Display Applicable Recipes

With the ProjectContext in place SBM checks all Conditions of recipes and their Actions to find applicable recipes. The resulting list of applicable recipes is then shown to the user to select and apply recipes against the scanned application.

Apply Recipe

The user applies a recipe from the list of applicable recipes.

Applying Recipe Actions

SBM provides the ProjectContext to the list of applicable Actions and each Action modifies the AST through the ProjectContext API. These modifications are only represented in memory.

Verify Application In Sync

After applying all Actions of the Recipe the changes need to be written back to filesystem. When sbm.gitSupportEnabled is true SBM verifies that nothing changed in the scanned project while the recipe was applied. If the git hash changed or non-indexed resources are found the changes are rolled back, the project must be synced, re-scanned and the recipe needs to be re-applied.

Writing Back Changes

When git support is disabled or the project is in sync the in-memory representation is written back to the file system.

Commit Changes

When git support is enabled SBM commits the changes applied by running the recipe and the next recipe can be applied.

Modules

Since 0.9.0 SBM starts to support multi module applications.

Spring Boot Resources

Spring RestController Bean

Classes annotated with Spring @RestController annotation can be found using the FindRestControllerBeans finder.

List<RestControllerBean> restController = projectContext.search(new FindRestControllerBeans());

List<RestMethod> restMethods = restController.get(0).getRestMethods();

restMethods.get(0).