Central data model classes for representing repository metadata structure and managing metadata at different directory levels in Maven repositories.
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 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: yyyyMMddHHmmssThe 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:
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 pluginReal-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:
The core model classes are designed to be resilient: