CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-openrewrite--rewrite-maven

OpenRewrite Maven parsing and refactoring library that provides Maven POM file parsing, analysis, and automated refactoring capabilities

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities and Helpers

Utility classes for common Maven operations including Maven wrapper support and dependency visualization.

Capabilities

Maven Wrapper Utilities

MavenWrapper

Utilities for working with Maven wrapper scripts and configuration.

/**
 * Utilities for working with Maven wrapper (mvnw) scripts
 */
public class MavenWrapper {
    /**
     * Check if project has Maven wrapper
     * @param projectRoot Project root directory
     * @return true if Maven wrapper exists
     */
    public static boolean hasMavenWrapper(Path projectRoot);
    
    /**
     * Get Maven wrapper version from project
     * @param projectRoot Project root directory
     * @return Maven wrapper version or null if not found
     */
    public static @Nullable String getWrapperVersion(Path projectRoot);
    
    /**
     * Update Maven wrapper to specified version
     * @param projectRoot Project root directory
     * @param version New Maven version
     * @throws IOException if update fails
     */
    public static void updateWrapper(Path projectRoot, String version) throws IOException;
    
    /**
     * Create Maven wrapper in project
     * @param projectRoot Project root directory
     * @param mavenVersion Maven version to use
     * @throws IOException if creation fails
     */
    public static void createWrapper(Path projectRoot, String mavenVersion) throws IOException;
    
    /**
     * Get Maven wrapper properties
     * @param projectRoot Project root directory
     * @return Properties from wrapper configuration
     */
    public static Properties getWrapperProperties(Path projectRoot);
}

Usage Examples:

Path projectRoot = Paths.get("/path/to/maven/project");

// Check for Maven wrapper
if (MavenWrapper.hasMavenWrapper(projectRoot)) {
    String version = MavenWrapper.getWrapperVersion(projectRoot);
    System.out.println("Maven wrapper version: " + version);
    
    // Update wrapper to newer version
    MavenWrapper.updateWrapper(projectRoot, "3.9.4");
} else {
    // Create new Maven wrapper
    MavenWrapper.createWrapper(projectRoot, "3.9.4");
}

// Get wrapper configuration
Properties props = MavenWrapper.getWrapperProperties(projectRoot);
String distributionUrl = props.getProperty("distributionUrl");
System.out.println("Distribution URL: " + distributionUrl);

Artifact Downloading

MavenArtifactDownloader

Utility for downloading Maven artifacts from repositories.

/**
 * Utility for downloading Maven artifacts from repositories
 */
public class MavenArtifactDownloader {
    /**
     * Create downloader with default configuration
     */
    public MavenArtifactDownloader();
    
    /**
     * Create downloader with custom repositories
     * @param repositories List of Maven repositories to use
     */
    public MavenArtifactDownloader(List<MavenRepository> repositories);
    
    /**
     * Create downloader with configuration
     * @param repositories List of Maven repositories
     * @param cache Optional artifact cache
     * @param timeout Download timeout in milliseconds
     */
    public MavenArtifactDownloader(List<MavenRepository> repositories, 
                                  @Nullable MavenArtifactCache cache,
                                  int timeout);
}

Key Methods:

/**
 * Download artifact JAR file
 * @param gav Group:Artifact:Version coordinate
 * @return Downloaded artifact bytes
 * @throws MavenDownloadingException if download fails
 */
public byte[] downloadArtifact(GroupArtifactVersion gav) throws MavenDownloadingException;

/**
 * Download artifact with classifier
 * @param gav Group:Artifact:Version coordinate  
 * @param classifier Artifact classifier (e.g., "sources", "javadoc")
 * @return Downloaded artifact bytes
 * @throws MavenDownloadingException if download fails
 */
public byte[] downloadArtifact(GroupArtifactVersion gav, String classifier) throws MavenDownloadingException;

/**
 * Download artifact POM file
 * @param gav Group:Artifact:Version coordinate
 * @return Downloaded POM content
 * @throws MavenDownloadingException if download fails
 */
public String downloadPom(GroupArtifactVersion gav) throws MavenDownloadingException;

/**
 * Download artifact metadata
 * @param ga Group:Artifact coordinate
 * @return Maven metadata information
 * @throws MavenDownloadingException if download fails
 */
public MavenMetadata downloadMetadata(GroupArtifact ga) throws MavenDownloadingException;

/**
 * Check if artifact exists in repositories
 * @param gav Group:Artifact:Version coordinate
 * @return true if artifact exists
 */
public boolean artifactExists(GroupArtifactVersion gav);

/**
 * Get available versions for artifact
 * @param ga Group:Artifact coordinate
 * @return List of available versions
 * @throws MavenDownloadingException if retrieval fails
 */
public List<String> getAvailableVersions(GroupArtifact ga) throws MavenDownloadingException;

Usage Examples:

// Create repositories
List<MavenRepository> repos = Arrays.asList(
    MavenRepository.builder()
        .id("central")
        .uri("https://repo1.maven.org/maven2/")
        .releases(true)
        .snapshots(false)
        .build(),
    MavenRepository.builder()
        .id("snapshots")
        .uri("https://oss.sonatype.org/content/repositories/snapshots/")
        .releases(false)
        .snapshots(true)
        .build()
);

// Create downloader
MavenArtifactDownloader downloader = new MavenArtifactDownloader(repos);

// Download specific artifact
GroupArtifactVersion gav = new GroupArtifactVersion("org.junit.jupiter", "junit-jupiter", "5.8.2");
try {
    byte[] artifactBytes = downloader.downloadArtifact(gav);
    System.out.println("Downloaded artifact: " + artifactBytes.length + " bytes");
    
    // Download sources
    byte[] sourcesBytes = downloader.downloadArtifact(gav, "sources");
    System.out.println("Downloaded sources: " + sourcesBytes.length + " bytes");
    
    // Download POM
    String pomContent = downloader.downloadPom(gav);
    System.out.println("Downloaded POM:\n" + pomContent);
    
} catch (MavenDownloadingException e) {
    System.err.println("Download failed: " + e.getMessage());
}

// Check artifact availability
GroupArtifact ga = new GroupArtifact("org.springframework", "spring-core");
if (downloader.artifactExists(new GroupArtifactVersion(ga.getGroupId(), ga.getArtifactId(), "5.3.21"))) {
    List<String> versions = downloader.getAvailableVersions(ga);
    System.out.println("Available versions: " + versions);
}

Dependency Visualization

PrintMavenAsDot

Recipe to visualize Maven dependencies as DOT graph format for Graphviz.

/**
 * Recipe to generate DOT graph representation of Maven dependencies
 */
public class PrintMavenAsDot extends Recipe {
    /**
     * Create recipe with default configuration
     */
    public PrintMavenAsDot();
    
    /**
     * Create recipe with scope filter
     * @param scope Optional scope to limit visualization (e.g., "compile", "test")
     */
    public PrintMavenAsDot(@Nullable String scope);
    
    /**
     * Create recipe with full configuration
     * @param scope Optional scope filter
     * @param includeTransitive Include transitive dependencies
     * @param maxDepth Maximum dependency depth to visualize
     */
    public PrintMavenAsDot(@Nullable String scope, boolean includeTransitive, int maxDepth);
}

Usage Examples:

// Generate DOT graph for all dependencies
PrintMavenAsDot dotGenerator = new PrintMavenAsDot();
RecipeRun run = dotGenerator.run(List.of(pomDocument), ctx);

// Get generated DOT content
List<PrintMavenAsDot.DotGraph> graphs = run.getDataTable(PrintMavenAsDot.DotGraph.class);
for (PrintMavenAsDot.DotGraph graph : graphs) {
    String dotContent = graph.getDotContent();
    
    // Save to file
    Files.write(Paths.get("dependencies.dot"), dotContent.getBytes());
    
    // Or render with Graphviz
    Process graphviz = Runtime.getRuntime().exec("dot -Tpng -o dependencies.png");
    try (OutputStream out = graphviz.getOutputStream()) {
        out.write(dotContent.getBytes());
    }
    graphviz.waitFor();
}

// Generate focused graph for compile dependencies only
PrintMavenAsDot compileGraph = new PrintMavenAsDot("compile", true, 3);
RecipeRun compileRun = compileGraph.run(List.of(pomDocument), ctx);

Version Retention Utilities

RetainVersions

Utility for version retention policies and cleanup operations.

/**
 * Utility for managing version retention policies
 */
public class RetainVersions {
    /**
     * Create retention policy with default settings
     */
    public RetainVersions();
    
    /**
     * Create retention policy with configuration
     * @param retainCount Number of versions to retain
     * @param retainDays Number of days to retain versions
     * @param retainSnapshots Whether to retain snapshot versions
     */
    public RetainVersions(int retainCount, int retainDays, boolean retainSnapshots);
}

Key Methods:

/**
 * Get versions to retain based on policy
 * @param availableVersions List of available versions
 * @return List of versions that should be retained
 */
public List<String> getVersionsToRetain(List<String> availableVersions);

/**
 * Get versions to delete based on policy
 * @param availableVersions List of available versions
 * @return List of versions that can be deleted
 */
public List<String> getVersionsToDelete(List<String> availableVersions);

/**
 * Check if version should be retained
 * @param version Version to check
 * @param availableVersions All available versions
 * @return true if version should be retained
 */
public boolean shouldRetain(String version, List<String> availableVersions);

Usage Examples:

// Create retention policy: keep 5 latest versions, 30 days, no snapshots
RetainVersions policy = new RetainVersions(5, 30, false);

List<String> availableVersions = Arrays.asList(
    "1.0.0", "1.1.0", "1.2.0", "1.3.0", "1.4.0", "1.5.0", 
    "2.0.0-SNAPSHOT", "1.6.0", "1.7.0"
);

List<String> toRetain = policy.getVersionsToRetain(availableVersions);
List<String> toDelete = policy.getVersionsToDelete(availableVersions);

System.out.println("Retain: " + toRetain);
System.out.println("Delete: " + toDelete);

Maven Settings Utilities

MavenSettings Helper Methods

/**
 * Additional helper methods for MavenSettings
 */
public class MavenSettings {
    /**
     * Load settings from default location (~/.m2/settings.xml)
     * @return MavenSettings instance or null if not found
     */
    public static @Nullable MavenSettings loadDefault();
    
    /**
     * Load settings from specific file
     * @param settingsFile Path to settings.xml file
     * @return MavenSettings instance
     * @throws IOException if file cannot be read
     */
    public static MavenSettings load(Path settingsFile) throws IOException;
    
    /**
     * Merge global and user settings
     * @param globalSettings Global settings (from Maven installation)  
     * @param userSettings User settings (from ~/.m2/settings.xml)
     * @return Merged settings
     */
    public static MavenSettings merge(@Nullable MavenSettings globalSettings, 
                                     @Nullable MavenSettings userSettings);
    
    /**
     * Get effective repositories (including mirrors)
     * @return List of effective repositories
     */
    public List<MavenRepository> getEffectiveRepositories();
    
    /**
     * Get server authentication for repository
     * @param repositoryId Repository ID
     * @return Server configuration or null if not found
     */
    public @Nullable Server getServer(String repositoryId);
    
    /**
     * Resolve property placeholders in settings
     * @param value Value that may contain placeholders
     * @return Resolved value
     */
    public String resolveProperty(String value);
}

Tag Insertion Utilities

MavenTagInsertionComparator

Comparator for ordering Maven POM elements according to Maven conventions.

/**
 * Comparator for ordering Maven POM elements according to standard conventions
 * Used to maintain proper element ordering when adding new elements
 */
public class MavenTagInsertionComparator implements Comparator<Content> {
    /**
     * Create comparator for specific parent tag
     * @param parentTagName Name of parent tag (e.g., "dependencies", "plugins")
     */
    public MavenTagInsertionComparator(String parentTagName);
    
    @Override
    public int compare(Content c1, Content c2);
    
    /**
     * Get standard ordering for Maven POM elements
     * @return Map of element names to their priority order
     */
    public static Map<String, Integer> getStandardOrdering();
}

Usage Examples:

// Use comparator when adding dependencies
MavenTagInsertionComparator comparator = new MavenTagInsertionComparator("dependencies");

// Sort existing dependencies
List<Xml.Tag> dependencies = getDependencyTags();
dependencies.sort((tag1, tag2) -> comparator.compare(tag1, tag2));

// Insert new dependency in correct position
Xml.Tag newDependency = createDependencyTag("org.junit.jupiter", "junit-jupiter", "5.8.2");
int insertPosition = Collections.binarySearch(dependencies, newDependency, comparator);
if (insertPosition < 0) {
    insertPosition = -insertPosition - 1;
}
dependencies.add(insertPosition, newDependency);

Assertion Utilities

Assertions

Test assertions for Maven-related functionality.

/**
 * Test assertions for Maven-related functionality
 * Used in testing Maven transformations and analysis
 */
public class Assertions {
    /**
     * Assert that POM contains dependency
     * @param pom POM to check
     * @param groupId Expected group ID
     * @param artifactId Expected artifact ID
     */
    public static void assertHasDependency(Pom pom, String groupId, String artifactId);
    
    /**
     * Assert that POM contains dependency with version
     * @param pom POM to check
     * @param groupId Expected group ID
     * @param artifactId Expected artifact ID
     * @param version Expected version
     */
    public static void assertHasDependency(Pom pom, String groupId, String artifactId, String version);
    
    /**
     * Assert that POM contains plugin
     * @param pom POM to check
     * @param groupId Expected plugin group ID
     * @param artifactId Expected plugin artifact ID
     */
    public static void assertHasPlugin(Pom pom, String groupId, String artifactId);
    
    /**
     * Assert that POM contains property
     * @param pom POM to check
     * @param key Expected property key
     * @param value Expected property value
     */
    public static void assertHasProperty(Pom pom, String key, String value);
    
    /**
     * Assert that dependency has scope
     * @param dependency Dependency to check
     * @param expectedScope Expected scope
     */
    public static void assertDependencyScope(Dependency dependency, Scope expectedScope);
    
    /**
     * Assert that dependencies are in correct order
     * @param dependencies List of dependencies to check
     */
    public static void assertDependencyOrder(List<Dependency> dependencies);
}

Usage Examples:

// In tests
@Test
public void testAddDependency() {
    AddDependency recipe = new AddDependency("org.junit.jupiter", "junit-jupiter", "5.8.2", 
                                           null, "test", null, null, null, null, null, null, null);
    
    RecipeRun run = recipe.run(List.of(pomDocument), ctx);
    Pom resultPom = getResultPom(run);
    
    // Assert dependency was added
    Assertions.assertHasDependency(resultPom, "org.junit.jupiter", "junit-jupiter");
    Assertions.assertHasDependency(resultPom, "org.junit.jupiter", "junit-jupiter", "5.8.2");
    
    // Assert dependency has correct scope
    Dependency junitDep = resultPom.getDependencies().stream()
        .filter(dep -> dep.getArtifactId().equals("junit-jupiter"))
        .findFirst()
        .orElse(null);
    
    assertNotNull(junitDep);
    Assertions.assertDependencyScope(junitDep, Scope.Test);
}

Trait System Integration

Maven Element Traits

/**
 * Factory class for creating Maven-specific traits
 */
public class Traits {
    /**
     * Create trait for Maven dependency elements
     * @param element Source element
     * @return MavenDependency trait
     */
    public static MavenDependency mavenDependency(SourceFile element);
    
    /**
     * Create trait for Maven plugin elements
     * @param element Source element
     * @return MavenPlugin trait  
     */
    public static MavenPlugin mavenPlugin(SourceFile element);
}

/**
 * Trait for Maven dependency elements
 */
public class MavenDependency {
    /**
     * Get dependency coordinate
     */
    public GroupArtifactVersion getCoordinate();
    
    /**
     * Get dependency scope
     */
    public Scope getScope();
    
    /**
     * Check if dependency is optional
     */
    public boolean isOptional();
    
    /**
     * Get dependency exclusions
     */
    public List<GroupArtifact> getExclusions();
}

/**
 * Trait for Maven plugin elements
 */
public class MavenPlugin {
    /**
     * Get plugin coordinate
     */
    public GroupArtifactVersion getCoordinate();
    
    /**
     * Get plugin configuration
     */
    public @Nullable Object getConfiguration();
    
    /**
     * Get plugin executions
     */
    public List<PluginExecution> getExecutions();
}

Complete Utility Usage Example

/**
 * Comprehensive example using multiple utilities together
 */
public class MavenProjectAnalyzer {
    public void analyzeProject(Path projectRoot) throws Exception {
        // Check for Maven wrapper
        if (MavenWrapper.hasMavenWrapper(projectRoot)) {
            String wrapperVersion = MavenWrapper.getWrapperVersion(projectRoot);
            System.out.println("Maven wrapper version: " + wrapperVersion);
        }
        
        // Load Maven settings
        MavenSettings settings = MavenSettings.loadDefault();
        List<MavenRepository> repositories = settings != null ? 
            settings.getEffectiveRepositories() : 
            Collections.singletonList(MavenRepository.MAVEN_CENTRAL);
        
        // Set up artifact downloader
        MavenArtifactDownloader downloader = new MavenArtifactDownloader(repositories);
        
        // Parse POM with caching
        InMemoryMavenPomCache pomCache = new InMemoryMavenPomCache();
        MavenParser parser = MavenParser.builder()
            .pomCache(pomCache)
            .build();
        
        Path pomFile = projectRoot.resolve("pom.xml");
        String pomContent = Files.readString(pomFile);
        
        ExecutionContext ctx = new InMemoryExecutionContext();
        List<SourceFile> parsed = parser.parse(ctx, pomContent);
        
        Xml.Document pomDoc = (Xml.Document) parsed.get(0);
        MavenResolutionResult result = pomDoc.getMarkers()
            .findFirst(MavenResolutionResult.class)
            .orElse(null);
        
        if (result != null) {
            ResolvedPom resolvedPom = result.getPom();
            
            // Generate dependency visualization
            PrintMavenAsDot dotGenerator = new PrintMavenAsDot("compile", true, 3);
            RecipeRun dotRun = dotGenerator.run(List.of(pomDoc), ctx);
            
            List<PrintMavenAsDot.DotGraph> graphs = dotRun.getDataTable(PrintMavenAsDot.DotGraph.class);
            if (!graphs.isEmpty()) {
                Files.write(projectRoot.resolve("dependencies.dot"), 
                           graphs.get(0).getDotContent().getBytes());
            }
            
            // Check for outdated dependencies
            for (ResolvedDependency dep : resolvedPom.getDependencies()) {
                GroupArtifact ga = new GroupArtifact(dep.getGroupId(), dep.getArtifactId());
                List<String> availableVersions = downloader.getAvailableVersions(ga);
                
                // Use retention policy to identify latest versions
                RetainVersions policy = new RetainVersions(1, Integer.MAX_VALUE, false);
                List<String> latest = policy.getVersionsToRetain(availableVersions);
                
                if (!latest.isEmpty() && !latest.get(0).equals(dep.getVersion())) {
                    System.out.println("Outdated dependency: " + dep.getGroupId() + ":" + 
                                     dep.getArtifactId() + " (" + dep.getVersion() + 
                                     " -> " + latest.get(0) + ")");
                }
            }
        }
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-openrewrite--rewrite-maven

docs

caching.md

core-parsing.md

data-model.md

index.md

recipes.md

search-analysis.md

utilities.md

tile.json