= Components

The following components can be used to parse a project, run recipes and write changes back to the filesystem.
These components are provided as Spring beans and can be injected into other Spring beans that require them.

== Injecting Spring Rewrite Commons Components
Spring Rewrite Commons offers components as Spring beans that and can be https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html[injected,window=_blank] into existing components.

[source, java]
....
@Autowired
private RewriteProjectParser parser;
....

== ProjectScanner
Scan a given path to a list of ``https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/Resource.html[Resource,window=_blank]``s using filter definitions provided through xref:properties.adoc[application properties].

[source, java]
....
Path baseDir = ...
List<Resource> resources = scanner.scan(baseDir);
....




== RewriteExecutionContext
OpenRewrite's `ExecutionContext` gets initialized during parsing.
This `ExecutionContext` is required to run recipes and for the inner workings of OpenRewrite.

== RecipeDiscovery
Discover OpenRewrite recipes on classpath.
These can be custom recipes or recipes provided through https://docs.openrewrite.org/recipes[OpenRewrite's Recipe Catalog]

=== Access the RecipeDiscovery
The `RecipeDiscovery` component is provided as Spring Bean and can be injected as such, e.g. by using `@Autowired`.

[source,java]
....
@Autowired
private RecipeDiscovery discovery;
....

=== Discover recipes by name
A single OpenRewrite recipe can be discovered by name.

[source,java]
....
Optional<Recipe> recipe = discovery.findRecipeByName("recipe name");
....

=== Discover all recipes
All available OpenRewrite recipes can be discovered.

[source,java]
....
List<Recipe> recipes = discovery.findAllRecipes();
....

== ProjectResourceSet
Abstraction of OpenRewrite SourceFiles that allows execution of recipes against the SourceFiles while changes are transparently synchronized with the initial list of SourceFiles.

=== Creating a ProjectResourceSet
`ProjectResourceSet` is not a Spring bean itself.
The `ProjectResourceSetFactory` is provided as Spring bean and can be injected

[source, java]
....
@Autowired
ProjectResourceSetFactory resourceSetFactory;
....

and used to create `ProjectResourceSet` instances

[source, java]
....
ProjectResourceSet resourceSet = resourceSetFactory.create(baseDir, lst);
....

=== Applying recipes

The `ProjectResourceSet` can be used to sequentially apply OpenRewrite recipes. The results from each recipe run is transparently merged back into the initial LST.

[source, java]
....
ProjectResourceSet rs = projectResourceSetFactory.create(baseDir, lst);

rs.apply(firstRecipe);
rs.apply(secondRecipe);
rs.apply(thirdRecipe);
....

== ProjectResourceSetSerializer
`ProjectResourceSetSerializer` helps to synchronize the modified in-memory representation of the scanned project to the filesystem, effectively applying the changes to the codebase (add, update, delete).

[source, java]
....
projectResourceSetSerializer.writeChanges(projectResourceSet);
....




== Listen to ParserEvents

``ParserEvent``s get published during parsing.
The events can be used to provide progress information to users.
This is especially useful when parsing large projects where parsing can take some time.


* `StartedParsingProjectEvent` - Gets published when the parsing started
* `ParsedResourceEvent` - Gets published  after every parsed pom or Java file
* `SuccessfullyParsedProjectEvent` - Gets published when the parsing was successful

[source,java]
.....
@EventListener(ParsedResourceEvent.class)
public void onParsedResourceEvent(ParsedResourceEvent event) {
    Parser.Input input = event.input();
    SourceFile sourceFile = event.sourceFile();
    log("parsed %s to %s".formatted(input.getRelativePath(), sourceFile.getClass().getName()));
}
.....