OpenRewrite Maven parsing and refactoring library that provides Maven POM file parsing, analysis, and automated refactoring capabilities
—
Essential parsing capabilities for converting Maven POM files to OpenRewrite AST and visitor patterns for transformations.
The primary entry point for parsing Maven POM files with full dependency resolution.
/**
* Parser that converts Maven POM XML files into OpenRewrite AST with dependency resolution
*/
public class MavenParser implements Parser;Builder Pattern:
/**
* Creates a builder for configuring MavenParser instances
* @return MavenParser.Builder for configuration
*/
public static MavenParser.Builder builder();
public static class MavenParser.Builder extends Parser.Builder;Usage Examples:
// Basic parser
MavenParser parser = MavenParser.builder().build();
// Parser with active profiles
MavenParser parser = MavenParser.builder()
.activeProfiles("dev", "integration-test")
.build();
// Parser with custom properties
MavenParser parser = MavenParser.builder()
.property("maven.compiler.source", "17")
.property("maven.compiler.target", "17")
.skipDependencyResolution(false)
.build();
// Parse POM files
ExecutionContext ctx = new InMemoryExecutionContext();
List<SourceFile> parsed = parser.parse(ctx, pomXmlContent);Configure parser behavior through the builder pattern.
/**
* Add multiple active profiles for POM resolution
* @param profiles Profile names to activate
* @return Builder for chaining
*/
public Builder activeProfiles(String... profiles);
/**
* Set a property for POM resolution
* @param key Property name
* @param value Property value
* @return Builder for chaining
*/
public Builder property(String key, String value);
/**
* Skip dependency resolution during parsing (faster but less complete)
* @param skip Whether to skip dependency resolution
* @return Builder for chaining
*/
public Builder skipDependencyResolution(boolean skip);Base visitor class for Maven POM transformations with Maven-specific functionality.
/**
* Base visitor for Maven POM transformations
* Extends XmlVisitor with Maven-specific methods and context
* @param <P> Parameter type for visitor methods
*/
public abstract class MavenVisitor<P> extends XmlVisitor<P>;Key Methods:
/**
* Visit a Maven POM document
* @param document XML document representing a Maven POM
* @param p Parameter passed to visit methods
* @return Potentially transformed document
*/
public Xml.Document visitDocument(Xml.Document document, P p);
/**
* Get the resolved POM for the current document being visited
* @return ResolvedPom instance with dependency resolution
*/
protected @Nullable ResolvedPom getResolutionResult();
/**
* Check if a dependency with given coordinates exists in the POM
* @param groupId Group ID to search for
* @param artifactId Artifact ID to search for
* @return true if dependency exists
*/
protected boolean hasExistingDependency(String groupId, String artifactId);
/**
* Add a dependency to the POM at the appropriate location
* @param tag XML tag to add dependency to
* @param dependency Dependency to add
* @param p Parameter for visitor
* @return Modified XML tag
*/
protected Xml.Tag addDependency(Xml.Tag tag, Dependency dependency, P p);Usage Examples:
// Custom visitor for transforming Maven POMs
public class CustomMavenVisitor extends MavenVisitor<ExecutionContext> {
@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if ("dependencies".equals(tag.getName())) {
// Add custom dependency management logic
ResolvedPom pom = getResolutionResult();
if (pom != null && !hasExistingDependency("org.junit.jupiter", "junit-jupiter")) {
// Add JUnit dependency
Dependency junit = Dependency.builder()
.groupId("org.junit.jupiter")
.artifactId("junit-jupiter")
.version("5.8.2")
.scope(Scope.Test)
.build();
return addDependency(tag, junit, ctx);
}
}
return super.visitTag(tag, ctx);
}
}
// Apply the visitor
ExecutionContext ctx = new InMemoryExecutionContext();
CustomMavenVisitor visitor = new CustomMavenVisitor();
Xml.Document transformed = visitor.visit(pomDocument, ctx);Identity-preserving visitor that maintains object identity when no changes are made.
/**
* Identity-preserving visitor for Maven transformations
* Only creates new objects when actual changes are made
* @param <P> Parameter type for visitor methods
*/
public class MavenIsoVisitor<P> extends MavenVisitor<P>;Usage Examples:
// Identity-preserving visitor for efficient transformations
public class UpdateVersionVisitor extends MavenIsoVisitor<ExecutionContext> {
private final String targetVersion;
public UpdateVersionVisitor(String targetVersion) {
this.targetVersion = targetVersion;
}
@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if ("version".equals(tag.getName()) && isProjectVersion(tag)) {
return tag.withValue(tag.getValue().withText(targetVersion));
}
return super.visitTag(tag, ctx);
}
private boolean isProjectVersion(Xml.Tag tag) {
return tag.getParent()
.map(parent -> "project".equals(parent.getName()))
.orElse(false);
}
}
// Apply the visitor
UpdateVersionVisitor visitor = new UpdateVersionVisitor("2.0.0");
Xml.Document updated = visitor.visit(pomDocument, ctx);Provides Maven-specific execution context with settings and profile information.
/**
* Maven-specific execution context with settings and profiles
*/
public class MavenExecutionContextView extends DelegatingExecutionContext;Key Methods:
/**
* Get Maven settings from the execution context
* @return MavenSettings instance or null if not available
*/
public @Nullable MavenSettings getSettings();
/**
* Get active Maven profiles
* @return Collection of active profile names
*/
public Collection<String> getActiveProfiles();
/**
* Create a view from an existing execution context
* @param ctx Execution context to wrap
* @return MavenExecutionContextView
*/
public static MavenExecutionContextView view(ExecutionContext ctx);Usage Examples:
// Configure Maven execution context
ExecutionContext ctx = new InMemoryExecutionContext();
MavenExecutionContextView mavenCtx = MavenExecutionContextView.view(ctx);
// Access Maven-specific configuration
MavenSettings settings = mavenCtx.getSettings();
Collection<String> profiles = mavenCtx.getActiveProfiles();
// Use in visitor
public class SettingsAwareVisitor extends MavenVisitor<ExecutionContext> {
@Override
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
MavenExecutionContextView mavenCtx = MavenExecutionContextView.view(ctx);
MavenSettings settings = mavenCtx.getSettings();
if (settings != null) {
// Use settings information for transformation logic
}
return super.visitDocument(document, ctx);
}
}Pre-defined XPath matchers for common Maven POM elements.
// XPath matchers available in MavenVisitor
protected static final String DEPENDENCY_MATCHER = "//dependencies/dependency";
protected static final String PLUGIN_MATCHER = "//plugins/plugin";
protected static final String PROPERTY_MATCHER = "//properties/*";Exception types for Maven parsing and processing errors.
/**
* Exception thrown when Maven artifact downloading fails
*/
public class MavenDownloadingException extends Exception;
/**
* Container for multiple Maven downloading exceptions
*/
public class MavenDownloadingExceptions extends Exception {
/**
* Get all contained exceptions
* @return List of individual downloading exceptions
*/
public List<MavenDownloadingException> getExceptions();
}Usage Examples:
try {
MavenParser parser = MavenParser.builder().build();
List<SourceFile> parsed = parser.parse(ctx, pomContent);
} catch (MavenDownloadingException e) {
System.err.println("Failed to download artifact: " + e.getMessage());
} catch (MavenDownloadingExceptions e) {
System.err.println("Multiple download failures:");
for (MavenDownloadingException exception : e.getExceptions()) {
System.err.println(" - " + exception.getMessage());
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-openrewrite--rewrite-maven