0
# Core Metadata Model
1
2
Central data model classes for representing repository metadata structure and managing metadata at different directory levels in Maven repositories.
3
4
## Capabilities
5
6
### Metadata Class
7
8
Root metadata class representing per-directory repository metadata for groupId, groupId/artifactId, or groupId/artifactId/version directories.
9
10
```java { .api }
11
/**
12
* Root metadata class for repository-metadata.xml files
13
* Supports three types of directory metadata:
14
* - groupId level: contains plugin mappings
15
* - groupId/artifactId level: contains versioning information
16
* - groupId/artifactId/version level: contains snapshot information
17
*/
18
public class Metadata implements Serializable, Cloneable {
19
// Constructors
20
public Metadata();
21
22
// Basic properties
23
public String getModelVersion();
24
public void setModelVersion(String modelVersion);
25
public String getGroupId();
26
public void setGroupId(String groupId);
27
public String getArtifactId();
28
public void setArtifactId(String artifactId);
29
public String getVersion();
30
public void setVersion(String version);
31
public String getModelEncoding();
32
public void setModelEncoding(String modelEncoding);
33
34
// Complex objects
35
public Versioning getVersioning();
36
public void setVersioning(Versioning versioning);
37
public List<Plugin> getPlugins();
38
public void setPlugins(List<Plugin> plugins);
39
40
// Plugin management
41
public void addPlugin(Plugin plugin);
42
public void removePlugin(Plugin plugin);
43
44
// Object operations
45
public Metadata clone();
46
47
// Merging functionality
48
public boolean merge(Metadata sourceMetadata);
49
}
50
```
51
52
**Usage Examples:**
53
54
```java
55
import org.apache.maven.artifact.repository.metadata.Metadata;
56
import org.apache.maven.artifact.repository.metadata.Plugin;
57
58
// Create metadata for groupId level (plugin mappings)
59
Metadata groupMetadata = new Metadata();
60
groupMetadata.setGroupId("org.apache.maven.plugins");
61
62
Plugin compilerPlugin = new Plugin();
63
compilerPlugin.setName("Apache Maven Compiler Plugin");
64
compilerPlugin.setPrefix("compiler");
65
compilerPlugin.setArtifactId("maven-compiler-plugin");
66
groupMetadata.addPlugin(compilerPlugin);
67
68
// Create metadata for groupId/artifactId level (versioning)
69
Metadata artifactMetadata = new Metadata();
70
artifactMetadata.setGroupId("com.example");
71
artifactMetadata.setArtifactId("my-library");
72
73
Versioning versioning = new Versioning();
74
versioning.addVersion("1.0.0");
75
versioning.addVersion("1.1.0");
76
versioning.setLatest("1.1.0");
77
versioning.setRelease("1.1.0");
78
artifactMetadata.setVersioning(versioning);
79
80
// Create metadata for snapshot version
81
Metadata snapshotMetadata = new Metadata();
82
snapshotMetadata.setGroupId("com.example");
83
snapshotMetadata.setArtifactId("my-library");
84
snapshotMetadata.setVersion("1.2.0-SNAPSHOT");
85
```
86
87
### Versioning Class
88
89
Versioning information for groupId/artifactId or groupId/artifactId/version directories, managing version lists, snapshots, and timestamps.
90
91
```java { .api }
92
/**
93
* Versioning information for artifacts and snapshots
94
* Used in both groupId/artifactId and groupId/artifactId/version contexts
95
*/
96
public class Versioning implements Serializable, Cloneable {
97
// Constructors
98
public Versioning();
99
100
// Version tracking
101
public String getLatest();
102
public void setLatest(String latest);
103
public String getRelease();
104
public void setRelease(String release);
105
public List<String> getVersions();
106
public void setVersions(List<String> versions);
107
public void addVersion(String version);
108
public void removeVersion(String version);
109
110
// Timestamp management
111
public String getLastUpdated();
112
public void setLastUpdated(String lastUpdated);
113
public void updateTimestamp();
114
public void setLastUpdatedTimestamp(Date date);
115
116
// Snapshot information
117
public Snapshot getSnapshot();
118
public void setSnapshot(Snapshot snapshot);
119
public List<SnapshotVersion> getSnapshotVersions();
120
public void setSnapshotVersions(List<SnapshotVersion> snapshotVersions);
121
public void addSnapshotVersion(SnapshotVersion snapshotVersion);
122
public void removeSnapshotVersion(SnapshotVersion snapshotVersion);
123
124
// Object operations
125
public Versioning clone();
126
}
127
```
128
129
**Usage Examples:**
130
131
```java
132
import org.apache.maven.artifact.repository.metadata.Versioning;
133
import org.apache.maven.artifact.repository.metadata.Snapshot;
134
import java.util.Date;
135
136
// Basic version management
137
Versioning versioning = new Versioning();
138
versioning.addVersion("1.0.0");
139
versioning.addVersion("1.1.0");
140
versioning.addVersion("1.2.0-SNAPSHOT");
141
versioning.setLatest("1.2.0-SNAPSHOT");
142
versioning.setRelease("1.1.0");
143
144
// Timestamp management
145
versioning.updateTimestamp(); // Sets to current UTC time
146
versioning.setLastUpdatedTimestamp(new Date()); // Custom timestamp
147
148
// Snapshot handling
149
Snapshot snapshot = new Snapshot();
150
snapshot.setTimestamp("20231201.143022");
151
snapshot.setBuildNumber(5);
152
snapshot.setLocalCopy(false);
153
versioning.setSnapshot(snapshot);
154
155
// Check timestamp format
156
String lastUpdated = versioning.getLastUpdated(); // Format: yyyyMMddHHmmss
157
```
158
159
### Metadata Merging
160
161
The merge functionality intelligently combines metadata from multiple sources with conflict resolution.
162
163
```java { .api }
164
/**
165
* Merge another metadata object into this one
166
* @param sourceMetadata - Source metadata to merge from
167
* @return true if any changes were made, false otherwise
168
*/
169
public boolean merge(Metadata sourceMetadata);
170
```
171
172
**Merging Behavior:**
173
174
- **Plugin merging**: Plugins are merged by prefix, avoiding duplicates
175
- **Version merging**: Version lists are combined, duplicates are removed
176
- **Timestamp precedence**: Newer timestamps take precedence for updates
177
- **Snapshot handling**: Supports both legacy and modern snapshot formats
178
- **Version compatibility**: Never converts between legacy and modern formats
179
180
**Usage Examples:**
181
182
```java
183
// Merge remote metadata with local metadata
184
Metadata localMetadata = readLocalMetadata();
185
Metadata remoteMetadata = readRemoteMetadata();
186
187
boolean changed = localMetadata.merge(remoteMetadata);
188
if (changed) {
189
writeMetadata(localMetadata);
190
System.out.println("Metadata updated with remote changes");
191
}
192
193
// Merge plugin information
194
Metadata groupMetadata = new Metadata();
195
Metadata pluginMetadata = new Metadata();
196
197
Plugin newPlugin = new Plugin();
198
newPlugin.setPrefix("surefire");
199
newPlugin.setArtifactId("maven-surefire-plugin");
200
newPlugin.setName("Maven Surefire Plugin");
201
pluginMetadata.addPlugin(newPlugin);
202
203
groupMetadata.merge(pluginMetadata); // Adds new plugin
204
```
205
206
### Complex Merge Scenario Example
207
208
Real-world example showing sophisticated metadata merging with version conflicts, timestamp precedence, and snapshot handling.
209
210
```java
211
import org.apache.maven.artifact.repository.metadata.*;
212
import java.util.Date;
213
214
public class ComplexMergeExample {
215
216
public void demonstrateComplexMerge() {
217
// Scenario: Merging local and remote metadata for a SNAPSHOT artifact
218
// with version conflicts and different timestamps
219
220
// Create local metadata (older)
221
Metadata localMetadata = new Metadata();
222
localMetadata.setGroupId("com.example");
223
localMetadata.setArtifactId("my-library");
224
localMetadata.setVersion("1.2.0-SNAPSHOT");
225
226
Versioning localVersioning = new Versioning();
227
localVersioning.addVersion("1.0.0");
228
localVersioning.addVersion("1.1.0");
229
localVersioning.setLatest("1.2.0-SNAPSHOT");
230
localVersioning.setRelease("1.1.0");
231
localVersioning.setLastUpdated("20231201120000"); // Older timestamp
232
233
// Local snapshot info (older build)
234
Snapshot localSnapshot = new Snapshot();
235
localSnapshot.setTimestamp("20231201.120000");
236
localSnapshot.setBuildNumber(3);
237
localSnapshot.setLocalCopy(false);
238
localVersioning.setSnapshot(localSnapshot);
239
240
// Local snapshot versions
241
SnapshotVersion localJar = new SnapshotVersion();
242
localJar.setExtension("jar");
243
localJar.setVersion("1.2.0-20231201.120000-3");
244
localJar.setUpdated("20231201120000");
245
localVersioning.addSnapshotVersion(localJar);
246
247
localMetadata.setVersioning(localVersioning);
248
249
// Create remote metadata (newer)
250
Metadata remoteMetadata = new Metadata();
251
remoteMetadata.setGroupId("com.example");
252
remoteMetadata.setArtifactId("my-library");
253
remoteMetadata.setVersion("1.2.0-SNAPSHOT");
254
255
Versioning remoteVersioning = new Versioning();
256
remoteVersioning.addVersion("1.0.0");
257
remoteVersioning.addVersion("1.1.0");
258
remoteVersioning.addVersion("1.1.1"); // New version from remote
259
remoteVersioning.setLatest("1.2.0-SNAPSHOT");
260
remoteVersioning.setRelease("1.1.1"); // Updated release
261
remoteVersioning.setLastUpdated("20231201143000"); // Newer timestamp
262
263
// Remote snapshot info (newer build)
264
Snapshot remoteSnapshot = new Snapshot();
265
remoteSnapshot.setTimestamp("20231201.143000");
266
remoteSnapshot.setBuildNumber(5); // Higher build number
267
remoteSnapshot.setLocalCopy(false);
268
remoteVersioning.setSnapshot(remoteSnapshot);
269
270
// Remote snapshot versions (more artifacts)
271
SnapshotVersion remoteJar = new SnapshotVersion();
272
remoteJar.setExtension("jar");
273
remoteJar.setVersion("1.2.0-20231201.143000-5");
274
remoteJar.setUpdated("20231201143000");
275
remoteVersioning.addSnapshotVersion(remoteJar);
276
277
SnapshotVersion remotePom = new SnapshotVersion();
278
remotePom.setExtension("pom");
279
remotePom.setVersion("1.2.0-20231201.143000-5");
280
remotePom.setUpdated("20231201143000");
281
remoteVersioning.addSnapshotVersion(remotePom);
282
283
SnapshotVersion remoteSources = new SnapshotVersion();
284
remoteSources.setClassifier("sources");
285
remoteSources.setExtension("jar");
286
remoteSources.setVersion("1.2.0-20231201.143000-5");
287
remoteSources.setUpdated("20231201143000");
288
remoteVersioning.addSnapshotVersion(remoteSources);
289
290
remoteMetadata.setVersioning(remoteVersioning);
291
292
// Perform the merge
293
System.out.println("=== Before Merge ===");
294
System.out.println("Local versions: " + localMetadata.getVersioning().getVersions());
295
System.out.println("Local release: " + localMetadata.getVersioning().getRelease());
296
System.out.println("Local timestamp: " + localMetadata.getVersioning().getLastUpdated());
297
System.out.println("Local build number: " + localMetadata.getVersioning().getSnapshot().getBuildNumber());
298
System.out.println("Local snapshot versions: " + localMetadata.getVersioning().getSnapshotVersions().size());
299
300
boolean changed = localMetadata.merge(remoteMetadata);
301
302
System.out.println("\n=== After Merge ===");
303
System.out.println("Merge changed metadata: " + changed);
304
System.out.println("Final versions: " + localMetadata.getVersioning().getVersions());
305
System.out.println("Final release: " + localMetadata.getVersioning().getRelease());
306
System.out.println("Final timestamp: " + localMetadata.getVersioning().getLastUpdated());
307
System.out.println("Final build number: " + localMetadata.getVersioning().getSnapshot().getBuildNumber());
308
System.out.println("Final snapshot versions: " + localMetadata.getVersioning().getSnapshotVersions().size());
309
310
// Verify merge results
311
Versioning finalVersioning = localMetadata.getVersioning();
312
313
// Versions should be merged (no duplicates)
314
assert finalVersioning.getVersions().contains("1.1.1") : "New version should be added";
315
assert finalVersioning.getVersions().size() == 3 : "Should have 3 unique versions";
316
317
// Timestamp precedence - remote was newer
318
assert "20231201143000".equals(finalVersioning.getLastUpdated()) : "Should use newer timestamp";
319
assert "1.1.1".equals(finalVersioning.getRelease()) : "Should use release from newer metadata";
320
321
// Snapshot data - remote was newer
322
assert finalVersioning.getSnapshot().getBuildNumber() == 5 : "Should use newer build number";
323
assert "20231201.143000".equals(finalVersioning.getSnapshot().getTimestamp()) : "Should use newer snapshot timestamp";
324
325
// Snapshot versions - should include all unique classifier/extension combinations
326
assert finalVersioning.getSnapshotVersions().size() == 3 : "Should have 3 snapshot versions (jar, pom, sources jar)";
327
328
System.out.println("\n✅ Complex merge completed successfully with proper conflict resolution");
329
}
330
}
331
```
332
333
This example demonstrates the sophisticated merging logic including:
334
- **Version deduplication**: New versions are added without duplicates
335
- **Timestamp precedence**: Newer timestamps take priority for updates
336
- **Snapshot handling**: Build numbers and timestamps are properly updated
337
- **Snapshot version merging**: Multiple classifier/extension combinations are preserved
338
- **Release tracking**: Release versions are updated based on timestamp precedence
339
340
## Error Handling
341
342
The core model classes are designed to be resilient:
343
344
- **Null safety**: Getters return empty collections rather than null
345
- **Clone support**: Deep cloning preserves all nested objects
346
- **Serialization**: All classes implement Serializable for persistence
347
- **Validation**: Merge operations validate data consistency