or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-model.mdindex.mdplugin-registry.mdsnapshot-management.mdxml-processing.md
tile.json

core-model.mddocs/

Core Metadata Model

Central data model classes for representing repository metadata structure and managing metadata at different directory levels in Maven repositories.

Capabilities

Metadata Class

Root metadata class representing per-directory repository metadata for groupId, groupId/artifactId, or groupId/artifactId/version directories.

/**
 * Root metadata class for repository-metadata.xml files
 * Supports three types of directory metadata:
 * - groupId level: contains plugin mappings
 * - groupId/artifactId level: contains versioning information
 * - groupId/artifactId/version level: contains snapshot information
 */
public class Metadata implements Serializable, Cloneable {
  // Constructors
  public Metadata();
  
  // Basic properties
  public String getModelVersion();
  public void setModelVersion(String modelVersion);
  public String getGroupId();
  public void setGroupId(String groupId);
  public String getArtifactId();
  public void setArtifactId(String artifactId);
  public String getVersion();
  public void setVersion(String version);
  public String getModelEncoding();
  public void setModelEncoding(String modelEncoding);
  
  // Complex objects
  public Versioning getVersioning();
  public void setVersioning(Versioning versioning);
  public List<Plugin> getPlugins();
  public void setPlugins(List<Plugin> plugins);
  
  // Plugin management
  public void addPlugin(Plugin plugin);
  public void removePlugin(Plugin plugin);
  
  // Object operations
  public Metadata clone();
  
  // Merging functionality
  public boolean merge(Metadata sourceMetadata);
}

Usage Examples:

import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.Plugin;

// Create metadata for groupId level (plugin mappings)
Metadata groupMetadata = new Metadata();
groupMetadata.setGroupId("org.apache.maven.plugins");

Plugin compilerPlugin = new Plugin();
compilerPlugin.setName("Apache Maven Compiler Plugin");
compilerPlugin.setPrefix("compiler");
compilerPlugin.setArtifactId("maven-compiler-plugin");
groupMetadata.addPlugin(compilerPlugin);

// Create metadata for groupId/artifactId level (versioning)
Metadata artifactMetadata = new Metadata();
artifactMetadata.setGroupId("com.example");
artifactMetadata.setArtifactId("my-library");

Versioning versioning = new Versioning();
versioning.addVersion("1.0.0");
versioning.addVersion("1.1.0");
versioning.setLatest("1.1.0");
versioning.setRelease("1.1.0");
artifactMetadata.setVersioning(versioning);

// Create metadata for snapshot version
Metadata snapshotMetadata = new Metadata();
snapshotMetadata.setGroupId("com.example");
snapshotMetadata.setArtifactId("my-library");
snapshotMetadata.setVersion("1.2.0-SNAPSHOT");

Versioning Class

Versioning information for groupId/artifactId or groupId/artifactId/version directories, managing version lists, snapshots, and timestamps.

/**
 * Versioning information for artifacts and snapshots
 * Used in both groupId/artifactId and groupId/artifactId/version contexts
 */
public class Versioning implements Serializable, Cloneable {
  // Constructors
  public Versioning();
  
  // Version tracking
  public String getLatest();
  public void setLatest(String latest);
  public String getRelease();
  public void setRelease(String release);
  public List<String> getVersions();
  public void setVersions(List<String> versions);
  public void addVersion(String version);
  public void removeVersion(String version);
  
  // Timestamp management
  public String getLastUpdated();
  public void setLastUpdated(String lastUpdated);
  public void updateTimestamp();
  public void setLastUpdatedTimestamp(Date date);
  
  // Snapshot information
  public Snapshot getSnapshot();
  public void setSnapshot(Snapshot snapshot);
  public List<SnapshotVersion> getSnapshotVersions();
  public void setSnapshotVersions(List<SnapshotVersion> snapshotVersions);
  public void addSnapshotVersion(SnapshotVersion snapshotVersion);
  public void removeSnapshotVersion(SnapshotVersion snapshotVersion);
  
  // Object operations
  public Versioning clone();
}

Usage Examples:

import org.apache.maven.artifact.repository.metadata.Versioning;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import java.util.Date;

// Basic version management
Versioning versioning = new Versioning();
versioning.addVersion("1.0.0");
versioning.addVersion("1.1.0");
versioning.addVersion("1.2.0-SNAPSHOT");
versioning.setLatest("1.2.0-SNAPSHOT");
versioning.setRelease("1.1.0");

// Timestamp management
versioning.updateTimestamp(); // Sets to current UTC time
versioning.setLastUpdatedTimestamp(new Date()); // Custom timestamp

// Snapshot handling
Snapshot snapshot = new Snapshot();
snapshot.setTimestamp("20231201.143022");
snapshot.setBuildNumber(5);
snapshot.setLocalCopy(false);
versioning.setSnapshot(snapshot);

// Check timestamp format
String lastUpdated = versioning.getLastUpdated(); // Format: yyyyMMddHHmmss

Metadata Merging

The merge functionality intelligently combines metadata from multiple sources with conflict resolution.

/**
 * Merge another metadata object into this one
 * @param sourceMetadata - Source metadata to merge from
 * @return true if any changes were made, false otherwise
 */
public boolean merge(Metadata sourceMetadata);

Merging Behavior:

  • Plugin merging: Plugins are merged by prefix, avoiding duplicates
  • Version merging: Version lists are combined, duplicates are removed
  • Timestamp precedence: Newer timestamps take precedence for updates
  • Snapshot handling: Supports both legacy and modern snapshot formats
  • Version compatibility: Never converts between legacy and modern formats

Usage Examples:

// Merge remote metadata with local metadata
Metadata localMetadata = readLocalMetadata();
Metadata remoteMetadata = readRemoteMetadata();

boolean changed = localMetadata.merge(remoteMetadata);
if (changed) {
    writeMetadata(localMetadata);
    System.out.println("Metadata updated with remote changes");
}

// Merge plugin information
Metadata groupMetadata = new Metadata();
Metadata pluginMetadata = new Metadata();

Plugin newPlugin = new Plugin();
newPlugin.setPrefix("surefire");
newPlugin.setArtifactId("maven-surefire-plugin");
newPlugin.setName("Maven Surefire Plugin");
pluginMetadata.addPlugin(newPlugin);

groupMetadata.merge(pluginMetadata); // Adds new plugin

Complex Merge Scenario Example

Real-world example showing sophisticated metadata merging with version conflicts, timestamp precedence, and snapshot handling.

import org.apache.maven.artifact.repository.metadata.*;
import java.util.Date;

public class ComplexMergeExample {
    
    public void demonstrateComplexMerge() {
        // Scenario: Merging local and remote metadata for a SNAPSHOT artifact
        // with version conflicts and different timestamps
        
        // Create local metadata (older)
        Metadata localMetadata = new Metadata();
        localMetadata.setGroupId("com.example");
        localMetadata.setArtifactId("my-library");
        localMetadata.setVersion("1.2.0-SNAPSHOT");
        
        Versioning localVersioning = new Versioning();
        localVersioning.addVersion("1.0.0");
        localVersioning.addVersion("1.1.0");
        localVersioning.setLatest("1.2.0-SNAPSHOT");
        localVersioning.setRelease("1.1.0");
        localVersioning.setLastUpdated("20231201120000"); // Older timestamp
        
        // Local snapshot info (older build)
        Snapshot localSnapshot = new Snapshot();
        localSnapshot.setTimestamp("20231201.120000");
        localSnapshot.setBuildNumber(3);
        localSnapshot.setLocalCopy(false);
        localVersioning.setSnapshot(localSnapshot);
        
        // Local snapshot versions
        SnapshotVersion localJar = new SnapshotVersion();
        localJar.setExtension("jar");
        localJar.setVersion("1.2.0-20231201.120000-3");
        localJar.setUpdated("20231201120000");
        localVersioning.addSnapshotVersion(localJar);
        
        localMetadata.setVersioning(localVersioning);
        
        // Create remote metadata (newer)
        Metadata remoteMetadata = new Metadata();
        remoteMetadata.setGroupId("com.example");
        remoteMetadata.setArtifactId("my-library");
        remoteMetadata.setVersion("1.2.0-SNAPSHOT");
        
        Versioning remoteVersioning = new Versioning();
        remoteVersioning.addVersion("1.0.0");
        remoteVersioning.addVersion("1.1.0");
        remoteVersioning.addVersion("1.1.1"); // New version from remote
        remoteVersioning.setLatest("1.2.0-SNAPSHOT");
        remoteVersioning.setRelease("1.1.1"); // Updated release
        remoteVersioning.setLastUpdated("20231201143000"); // Newer timestamp
        
        // Remote snapshot info (newer build)
        Snapshot remoteSnapshot = new Snapshot();
        remoteSnapshot.setTimestamp("20231201.143000");
        remoteSnapshot.setBuildNumber(5); // Higher build number
        remoteSnapshot.setLocalCopy(false);
        remoteVersioning.setSnapshot(remoteSnapshot);
        
        // Remote snapshot versions (more artifacts)
        SnapshotVersion remoteJar = new SnapshotVersion();
        remoteJar.setExtension("jar");
        remoteJar.setVersion("1.2.0-20231201.143000-5");
        remoteJar.setUpdated("20231201143000");
        remoteVersioning.addSnapshotVersion(remoteJar);
        
        SnapshotVersion remotePom = new SnapshotVersion();
        remotePom.setExtension("pom");
        remotePom.setVersion("1.2.0-20231201.143000-5");
        remotePom.setUpdated("20231201143000");
        remoteVersioning.addSnapshotVersion(remotePom);
        
        SnapshotVersion remoteSources = new SnapshotVersion();
        remoteSources.setClassifier("sources");
        remoteSources.setExtension("jar");
        remoteSources.setVersion("1.2.0-20231201.143000-5");
        remoteSources.setUpdated("20231201143000");
        remoteVersioning.addSnapshotVersion(remoteSources);
        
        remoteMetadata.setVersioning(remoteVersioning);
        
        // Perform the merge
        System.out.println("=== Before Merge ===");
        System.out.println("Local versions: " + localMetadata.getVersioning().getVersions());
        System.out.println("Local release: " + localMetadata.getVersioning().getRelease());
        System.out.println("Local timestamp: " + localMetadata.getVersioning().getLastUpdated());
        System.out.println("Local build number: " + localMetadata.getVersioning().getSnapshot().getBuildNumber());
        System.out.println("Local snapshot versions: " + localMetadata.getVersioning().getSnapshotVersions().size());
        
        boolean changed = localMetadata.merge(remoteMetadata);
        
        System.out.println("\n=== After Merge ===");
        System.out.println("Merge changed metadata: " + changed);
        System.out.println("Final versions: " + localMetadata.getVersioning().getVersions());
        System.out.println("Final release: " + localMetadata.getVersioning().getRelease());
        System.out.println("Final timestamp: " + localMetadata.getVersioning().getLastUpdated());
        System.out.println("Final build number: " + localMetadata.getVersioning().getSnapshot().getBuildNumber());
        System.out.println("Final snapshot versions: " + localMetadata.getVersioning().getSnapshotVersions().size());
        
        // Verify merge results
        Versioning finalVersioning = localMetadata.getVersioning();
        
        // Versions should be merged (no duplicates)
        assert finalVersioning.getVersions().contains("1.1.1") : "New version should be added";
        assert finalVersioning.getVersions().size() == 3 : "Should have 3 unique versions";
        
        // Timestamp precedence - remote was newer
        assert "20231201143000".equals(finalVersioning.getLastUpdated()) : "Should use newer timestamp";
        assert "1.1.1".equals(finalVersioning.getRelease()) : "Should use release from newer metadata";
        
        // Snapshot data - remote was newer
        assert finalVersioning.getSnapshot().getBuildNumber() == 5 : "Should use newer build number";
        assert "20231201.143000".equals(finalVersioning.getSnapshot().getTimestamp()) : "Should use newer snapshot timestamp";
        
        // Snapshot versions - should include all unique classifier/extension combinations
        assert finalVersioning.getSnapshotVersions().size() == 3 : "Should have 3 snapshot versions (jar, pom, sources jar)";
        
        System.out.println("\n✅ Complex merge completed successfully with proper conflict resolution");
    }
}

This example demonstrates the sophisticated merging logic including:

  • Version deduplication: New versions are added without duplicates
  • Timestamp precedence: Newer timestamps take priority for updates
  • Snapshot handling: Build numbers and timestamps are properly updated
  • Snapshot version merging: Multiple classifier/extension combinations are preserved
  • Release tracking: Release versions are updated based on timestamp precedence

Error Handling

The core model classes are designed to be resilient:

  • Null safety: Getters return empty collections rather than null
  • Clone support: Deep cloning preserves all nested objects
  • Serialization: All classes implement Serializable for persistence
  • Validation: Merge operations validate data consistency