0
# Metadata Processing
1
2
Dependency metadata processing, graph management, and classpath transformation for Maven2 compatibility patterns.
3
4
## Capabilities
5
6
### MetadataSource
7
8
Interface for retrieving metadata from repositories.
9
10
```java { .api }
11
/**
12
* Interface for retrieving metadata from repositories
13
*/
14
public interface MetadataSource {
15
/**
16
* Role constant for Plexus component lookup
17
*/
18
String ROLE = MetadataSource.class.getName();
19
20
/**
21
* Retrieves metadata for an artifact from repositories
22
* @param artifact artifact metadata to retrieve
23
* @param localRepository local repository
24
* @param remoteRepositories list of remote repositories to search
25
* @return MetadataResolution containing retrieved metadata
26
* @throws MetadataRetrievalException if retrieval fails
27
*/
28
MetadataResolution retrieve(ArtifactMetadata artifact, ArtifactRepository localRepository,
29
List<ArtifactRepository> remoteRepositories)
30
throws MetadataRetrievalException;
31
}
32
```
33
34
### DefaultMetadataSource
35
36
Default implementation of MetadataSource.
37
38
```java { .api }
39
/**
40
* Default implementation of MetadataSource
41
*/
42
public class DefaultMetadataSource implements MetadataSource {
43
/**
44
* Retrieves metadata for an artifact from repositories
45
*/
46
public MetadataResolution retrieve(ArtifactMetadata artifact, ArtifactRepository localRepository,
47
List<ArtifactRepository> remoteRepositories)
48
throws MetadataRetrievalException;
49
}
50
```
51
52
### ClasspathTransformation
53
54
Interface for transforming metadata graphs into classpath containers.
55
56
```java { .api }
57
/**
58
* Interface for transforming metadata graphs into classpath containers
59
*/
60
public interface ClasspathTransformation {
61
/**
62
* Role constant for Plexus component lookup
63
*/
64
String ROLE = ClasspathTransformation.class.getName();
65
66
/**
67
* Transforms a metadata graph into a classpath container
68
* @param dirtyGraph metadata graph to transform
69
* @param scope artifact scope for filtering
70
* @param resolve whether to resolve artifacts during transformation
71
* @return ClasspathContainer with transformed classpath
72
* @throws ClasspathTransformationException if transformation fails
73
*/
74
ClasspathContainer transform(MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve)
75
throws ClasspathTransformationException;
76
}
77
```
78
79
### DefaultClasspathTransformation
80
81
Default implementation of ClasspathTransformation.
82
83
```java { .api }
84
/**
85
* Default implementation of ClasspathTransformation
86
*/
87
public class DefaultClasspathTransformation implements ClasspathTransformation {
88
/**
89
* Transforms a metadata graph into a classpath container
90
*/
91
public ClasspathContainer transform(MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve)
92
throws ClasspathTransformationException;
93
}
94
```
95
96
### GraphConflictResolver
97
98
Interface for resolving conflicts in metadata graphs.
99
100
```java { .api }
101
/**
102
* Interface for resolving conflicts in metadata graphs
103
*/
104
public interface GraphConflictResolver {
105
/**
106
* Role constant for Plexus component lookup
107
*/
108
String ROLE = GraphConflictResolver.class.getName();
109
110
/**
111
* Resolves conflicts in a metadata graph
112
* @param graph metadata graph with potential conflicts
113
* @param scope artifact scope for resolution context
114
* @param localRepository local repository
115
* @return MetadataGraph with conflicts resolved
116
* @throws GraphConflictResolutionException if resolution fails
117
*/
118
MetadataGraph resolveConflicts(MetadataGraph graph, ArtifactScopeEnum scope,
119
ArtifactRepository localRepository)
120
throws GraphConflictResolutionException;
121
}
122
```
123
124
## Metadata Graph Components
125
126
### MetadataGraph
127
128
Represents dependency metadata as a directed graph.
129
130
```java { .api }
131
/**
132
* Represents dependency metadata as a directed graph
133
*/
134
public class MetadataGraph {
135
/**
136
* Creates empty metadata graph
137
*/
138
public MetadataGraph();
139
140
/**
141
* Creates metadata graph with root vertex
142
* @param root root vertex for the graph
143
*/
144
public MetadataGraph(MetadataGraphVertex root);
145
146
/**
147
* Gets the root vertex of the graph
148
* @return root MetadataGraphVertex
149
*/
150
public MetadataGraphVertex getRoot();
151
152
/**
153
* Sets the root vertex of the graph
154
* @param root root vertex to set
155
*/
156
public void setRoot(MetadataGraphVertex root);
157
158
/**
159
* Gets all vertices in the graph
160
* @return Collection of MetadataGraphVertex objects
161
*/
162
public Collection<MetadataGraphVertex> getVertices();
163
164
/**
165
* Adds a vertex to the graph
166
* @param vertex vertex to add
167
*/
168
public void addVertex(MetadataGraphVertex vertex);
169
170
/**
171
* Gets all edges in the graph
172
* @return Collection of MetadataGraphEdge objects
173
*/
174
public Collection<MetadataGraphEdge> getEdges();
175
176
/**
177
* Adds an edge to the graph
178
* @param edge edge to add
179
*/
180
public void addEdge(MetadataGraphEdge edge);
181
}
182
```
183
184
### MetadataGraphVertex
185
186
Represents a vertex (node) in the metadata graph.
187
188
```java { .api }
189
/**
190
* Represents a vertex (node) in the metadata graph
191
*/
192
public class MetadataGraphVertex {
193
/**
194
* Creates vertex with artifact metadata
195
* @param metadata artifact metadata for this vertex
196
*/
197
public MetadataGraphVertex(ArtifactMetadata metadata);
198
199
/**
200
* Gets the artifact metadata for this vertex
201
* @return ArtifactMetadata object
202
*/
203
public ArtifactMetadata getMetadata();
204
205
/**
206
* Sets the artifact metadata for this vertex
207
* @param metadata artifact metadata to set
208
*/
209
public void setMetadata(ArtifactMetadata metadata);
210
211
/**
212
* Gets incoming edges to this vertex
213
* @return List of incoming MetadataGraphEdge objects
214
*/
215
public List<MetadataGraphEdge> getIncomingEdges();
216
217
/**
218
* Gets outgoing edges from this vertex
219
* @return List of outgoing MetadataGraphEdge objects
220
*/
221
public List<MetadataGraphEdge> getOutgoingEdges();
222
223
/**
224
* Adds an incoming edge
225
* @param edge incoming edge to add
226
*/
227
public void addIncomingEdge(MetadataGraphEdge edge);
228
229
/**
230
* Adds an outgoing edge
231
* @param edge outgoing edge to add
232
*/
233
public void addOutgoingEdge(MetadataGraphEdge edge);
234
}
235
```
236
237
### MetadataGraphEdge
238
239
Represents an edge (dependency relationship) in the metadata graph.
240
241
```java { .api }
242
/**
243
* Represents an edge (dependency relationship) in the metadata graph
244
*/
245
public class MetadataGraphEdge {
246
/**
247
* Creates edge between vertices
248
* @param from source vertex
249
* @param to target vertex
250
* @param scope dependency scope
251
*/
252
public MetadataGraphEdge(MetadataGraphVertex from, MetadataGraphVertex to, ArtifactScopeEnum scope);
253
254
/**
255
* Gets the source vertex
256
* @return source MetadataGraphVertex
257
*/
258
public MetadataGraphVertex getFrom();
259
260
/**
261
* Gets the target vertex
262
* @return target MetadataGraphVertex
263
*/
264
public MetadataGraphVertex getTo();
265
266
/**
267
* Gets the dependency scope
268
* @return ArtifactScopeEnum representing the scope
269
*/
270
public ArtifactScopeEnum getScope();
271
272
/**
273
* Sets the dependency scope
274
* @param scope scope to set
275
*/
276
public void setScope(ArtifactScopeEnum scope);
277
278
/**
279
* Checks if this is an optional dependency
280
* @return true if dependency is optional
281
*/
282
public boolean isOptional();
283
284
/**
285
* Sets whether this is an optional dependency
286
* @param optional true if dependency should be optional
287
*/
288
public void setOptional(boolean optional);
289
}
290
```
291
292
### ClasspathContainer
293
294
Container for classpath artifacts after transformation.
295
296
```java { .api }
297
/**
298
* Container for classpath artifacts after transformation
299
*/
300
public class ClasspathContainer {
301
/**
302
* Creates empty classpath container
303
*/
304
public ClasspathContainer();
305
306
/**
307
* Gets classpath artifacts
308
* @return List of Artifact objects in classpath order
309
*/
310
public List<Artifact> getClasspath();
311
312
/**
313
* Sets classpath artifacts
314
* @param classpath list of artifacts to set
315
*/
316
public void setClasspath(List<Artifact> classpath);
317
318
/**
319
* Adds an artifact to the classpath
320
* @param artifact artifact to add
321
*/
322
public void addArtifact(Artifact artifact);
323
324
/**
325
* Gets conflicted dependencies
326
* @return Map of conflicted artifacts with their alternatives
327
*/
328
public Map<Artifact, List<Artifact>> getConflicts();
329
330
/**
331
* Adds a conflict resolution
332
* @param chosen chosen artifact
333
* @param alternatives list of alternative artifacts that were rejected
334
*/
335
public void addConflict(Artifact chosen, List<Artifact> alternatives);
336
}
337
```
338
339
## Usage Examples
340
341
### Basic Metadata Retrieval
342
343
```java
344
import org.apache.maven.repository.metadata.MetadataSource;
345
import org.apache.maven.repository.metadata.DefaultMetadataSource;
346
import org.apache.maven.repository.metadata.MetadataResolution;
347
348
// Retrieve metadata for an artifact
349
MetadataSource metadataSource = new DefaultMetadataSource();
350
ArtifactMetadata artifactMetadata = // ... create artifact metadata
351
352
try {
353
MetadataResolution resolution = metadataSource.retrieve(
354
artifactMetadata,
355
localRepository,
356
remoteRepositories
357
);
358
359
System.out.println("Metadata retrieved successfully");
360
MetadataGraph graph = resolution.getMetadataGraph();
361
System.out.println("Graph has " + graph.getVertices().size() + " vertices");
362
363
} catch (MetadataRetrievalException e) {
364
System.err.println("Metadata retrieval failed: " + e.getMessage());
365
}
366
```
367
368
### Classpath Transformation
369
370
```java
371
import org.apache.maven.repository.metadata.ClasspathTransformation;
372
import org.apache.maven.repository.metadata.DefaultClasspathTransformation;
373
import org.apache.maven.repository.metadata.ClasspathContainer;
374
import org.apache.maven.artifact.ArtifactScopeEnum;
375
376
// Transform metadata graph to classpath
377
ClasspathTransformation transformation = new DefaultClasspathTransformation();
378
MetadataGraph graph = // ... obtain metadata graph
379
380
try {
381
ClasspathContainer container = transformation.transform(
382
graph,
383
ArtifactScopeEnum.runtime,
384
true // resolve artifacts
385
);
386
387
List<Artifact> classpath = container.getClasspath();
388
System.out.println("Classpath contains " + classpath.size() + " artifacts");
389
390
// Print classpath
391
for (Artifact artifact : classpath) {
392
System.out.println(" " + artifact.getGroupId() + ":" + artifact.getArtifactId() +
393
":" + artifact.getVersion());
394
}
395
396
// Check for conflicts
397
Map<Artifact, List<Artifact>> conflicts = container.getConflicts();
398
if (!conflicts.isEmpty()) {
399
System.out.println("Resolved " + conflicts.size() + " conflicts");
400
}
401
402
} catch (ClasspathTransformationException e) {
403
System.err.println("Classpath transformation failed: " + e.getMessage());
404
}
405
```
406
407
### Building Metadata Graph
408
409
```java
410
// Build metadata graph manually
411
MetadataGraph graph = new MetadataGraph();
412
413
// Create root vertex
414
ArtifactMetadata rootMetadata = // ... create root artifact metadata
415
MetadataGraphVertex rootVertex = new MetadataGraphVertex(rootMetadata);
416
graph.setRoot(rootVertex);
417
418
// Add dependency vertices
419
ArtifactMetadata depMetadata = // ... create dependency metadata
420
MetadataGraphVertex depVertex = new MetadataGraphVertex(depMetadata);
421
graph.addVertex(depVertex);
422
423
// Create edge between root and dependency
424
MetadataGraphEdge edge = new MetadataGraphEdge(
425
rootVertex,
426
depVertex,
427
ArtifactScopeEnum.compile
428
);
429
graph.addEdge(edge);
430
431
// Add edges to vertices
432
rootVertex.addOutgoingEdge(edge);
433
depVertex.addIncomingEdge(edge);
434
435
System.out.println("Created graph with " + graph.getVertices().size() + " vertices");
436
System.out.println("Graph has " + graph.getEdges().size() + " edges");
437
```
438
439
### Conflict Resolution
440
441
```java
442
import org.apache.maven.repository.metadata.GraphConflictResolver;
443
444
// Resolve conflicts in metadata graph
445
GraphConflictResolver resolver = // ... get resolver instance
446
MetadataGraph conflictedGraph = // ... graph with conflicts
447
448
try {
449
MetadataGraph resolvedGraph = resolver.resolveConflicts(
450
conflictedGraph,
451
ArtifactScopeEnum.compile,
452
localRepository
453
);
454
455
System.out.println("Conflicts resolved");
456
System.out.println("Resolved graph has " + resolvedGraph.getVertices().size() + " vertices");
457
458
} catch (GraphConflictResolutionException e) {
459
System.err.println("Conflict resolution failed: " + e.getMessage());
460
}
461
```
462
463
### Complete Metadata Processing Workflow
464
465
```java
466
public ClasspathContainer processMetadata(ArtifactMetadata rootArtifact) {
467
try {
468
// Step 1: Retrieve metadata
469
MetadataSource metadataSource = new DefaultMetadataSource();
470
MetadataResolution resolution = metadataSource.retrieve(
471
rootArtifact,
472
localRepository,
473
remoteRepositories
474
);
475
MetadataGraph graph = resolution.getMetadataGraph();
476
477
// Step 2: Resolve conflicts
478
GraphConflictResolver resolver = // ... get resolver
479
MetadataGraph resolvedGraph = resolver.resolveConflicts(
480
graph,
481
ArtifactScopeEnum.runtime,
482
localRepository
483
);
484
485
// Step 3: Transform to classpath
486
ClasspathTransformation transformation = new DefaultClasspathTransformation();
487
ClasspathContainer container = transformation.transform(
488
resolvedGraph,
489
ArtifactScopeEnum.runtime,
490
true
491
);
492
493
// Step 4: Report results
494
System.out.println("Processed metadata for " + rootArtifact);
495
System.out.println("Final classpath: " + container.getClasspath().size() + " artifacts");
496
System.out.println("Conflicts resolved: " + container.getConflicts().size());
497
498
return container;
499
500
} catch (Exception e) {
501
throw new RuntimeException("Metadata processing failed", e);
502
}
503
}
504
```
505
506
## Exception Handling
507
508
### MetadataRetrievalException
509
510
```java { .api }
511
/**
512
* Exception thrown when metadata retrieval fails
513
*/
514
public class MetadataRetrievalException extends Exception {
515
/**
516
* Creates exception with message
517
* @param message error message
518
*/
519
public MetadataRetrievalException(String message);
520
521
/**
522
* Creates exception with message and cause
523
* @param message error message
524
* @param cause underlying cause
525
*/
526
public MetadataRetrievalException(String message, Throwable cause);
527
}
528
```
529
530
### ClasspathTransformationException
531
532
```java { .api }
533
/**
534
* Exception thrown when classpath transformation fails
535
*/
536
public class ClasspathTransformationException extends Exception {
537
/**
538
* Creates exception with message
539
* @param message error message
540
*/
541
public ClasspathTransformationException(String message);
542
543
/**
544
* Creates exception with message and cause
545
* @param message error message
546
* @param cause underlying cause
547
*/
548
public ClasspathTransformationException(String message, Throwable cause);
549
}
550
```
551
552
### GraphConflictResolutionException
553
554
```java { .api }
555
/**
556
* Exception thrown when graph conflict resolution fails
557
*/
558
public class GraphConflictResolutionException extends Exception {
559
/**
560
* Creates exception with message
561
* @param message error message
562
*/
563
public GraphConflictResolutionException(String message);
564
565
/**
566
* Creates exception with message and cause
567
* @param message error message
568
* @param cause underlying cause
569
*/
570
public GraphConflictResolutionException(String message, Throwable cause);
571
}
572
```
573
574
## Migration Notes
575
576
The metadata processing system in maven-compat is maintained for backward compatibility. Modern Maven 3.x applications use the Eclipse Aether dependency resolution system instead of this legacy metadata graph approach.