0
# Core Parsing and Visitor Functionality
1
2
Essential parsing capabilities for converting Maven POM files to OpenRewrite AST and visitor patterns for transformations.
3
4
## Capabilities
5
6
### MavenParser
7
8
The primary entry point for parsing Maven POM files with full dependency resolution.
9
10
```java { .api }
11
/**
12
* Parser that converts Maven POM XML files into OpenRewrite AST with dependency resolution
13
*/
14
public class MavenParser implements Parser;
15
```
16
17
**Builder Pattern:**
18
19
```java { .api }
20
/**
21
* Creates a builder for configuring MavenParser instances
22
* @return MavenParser.Builder for configuration
23
*/
24
public static MavenParser.Builder builder();
25
26
public static class MavenParser.Builder extends Parser.Builder;
27
```
28
29
**Usage Examples:**
30
31
```java
32
// Basic parser
33
MavenParser parser = MavenParser.builder().build();
34
35
// Parser with active profiles
36
MavenParser parser = MavenParser.builder()
37
.activeProfiles("dev", "integration-test")
38
.build();
39
40
// Parser with custom properties
41
MavenParser parser = MavenParser.builder()
42
.property("maven.compiler.source", "17")
43
.property("maven.compiler.target", "17")
44
.skipDependencyResolution(false)
45
.build();
46
47
// Parse POM files
48
ExecutionContext ctx = new InMemoryExecutionContext();
49
List<SourceFile> parsed = parser.parse(ctx, pomXmlContent);
50
```
51
52
### MavenParser.Builder Configuration
53
54
Configure parser behavior through the builder pattern.
55
56
```java { .api }
57
/**
58
* Add multiple active profiles for POM resolution
59
* @param profiles Profile names to activate
60
* @return Builder for chaining
61
*/
62
public Builder activeProfiles(String... profiles);
63
64
/**
65
* Set a property for POM resolution
66
* @param key Property name
67
* @param value Property value
68
* @return Builder for chaining
69
*/
70
public Builder property(String key, String value);
71
72
/**
73
* Skip dependency resolution during parsing (faster but less complete)
74
* @param skip Whether to skip dependency resolution
75
* @return Builder for chaining
76
*/
77
public Builder skipDependencyResolution(boolean skip);
78
```
79
80
### MavenVisitor
81
82
Base visitor class for Maven POM transformations with Maven-specific functionality.
83
84
```java { .api }
85
/**
86
* Base visitor for Maven POM transformations
87
* Extends XmlVisitor with Maven-specific methods and context
88
* @param <P> Parameter type for visitor methods
89
*/
90
public abstract class MavenVisitor<P> extends XmlVisitor<P>;
91
```
92
93
**Key Methods:**
94
95
```java { .api }
96
/**
97
* Visit a Maven POM document
98
* @param document XML document representing a Maven POM
99
* @param p Parameter passed to visit methods
100
* @return Potentially transformed document
101
*/
102
public Xml.Document visitDocument(Xml.Document document, P p);
103
104
/**
105
* Get the resolved POM for the current document being visited
106
* @return ResolvedPom instance with dependency resolution
107
*/
108
protected @Nullable ResolvedPom getResolutionResult();
109
110
/**
111
* Check if a dependency with given coordinates exists in the POM
112
* @param groupId Group ID to search for
113
* @param artifactId Artifact ID to search for
114
* @return true if dependency exists
115
*/
116
protected boolean hasExistingDependency(String groupId, String artifactId);
117
118
/**
119
* Add a dependency to the POM at the appropriate location
120
* @param tag XML tag to add dependency to
121
* @param dependency Dependency to add
122
* @param p Parameter for visitor
123
* @return Modified XML tag
124
*/
125
protected Xml.Tag addDependency(Xml.Tag tag, Dependency dependency, P p);
126
```
127
128
**Usage Examples:**
129
130
```java
131
// Custom visitor for transforming Maven POMs
132
public class CustomMavenVisitor extends MavenVisitor<ExecutionContext> {
133
134
@Override
135
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
136
if ("dependencies".equals(tag.getName())) {
137
// Add custom dependency management logic
138
ResolvedPom pom = getResolutionResult();
139
if (pom != null && !hasExistingDependency("org.junit.jupiter", "junit-jupiter")) {
140
// Add JUnit dependency
141
Dependency junit = Dependency.builder()
142
.groupId("org.junit.jupiter")
143
.artifactId("junit-jupiter")
144
.version("5.8.2")
145
.scope(Scope.Test)
146
.build();
147
return addDependency(tag, junit, ctx);
148
}
149
}
150
return super.visitTag(tag, ctx);
151
}
152
}
153
154
// Apply the visitor
155
ExecutionContext ctx = new InMemoryExecutionContext();
156
CustomMavenVisitor visitor = new CustomMavenVisitor();
157
Xml.Document transformed = visitor.visit(pomDocument, ctx);
158
```
159
160
### MavenIsoVisitor
161
162
Identity-preserving visitor that maintains object identity when no changes are made.
163
164
```java { .api }
165
/**
166
* Identity-preserving visitor for Maven transformations
167
* Only creates new objects when actual changes are made
168
* @param <P> Parameter type for visitor methods
169
*/
170
public class MavenIsoVisitor<P> extends MavenVisitor<P>;
171
```
172
173
**Usage Examples:**
174
175
```java
176
// Identity-preserving visitor for efficient transformations
177
public class UpdateVersionVisitor extends MavenIsoVisitor<ExecutionContext> {
178
179
private final String targetVersion;
180
181
public UpdateVersionVisitor(String targetVersion) {
182
this.targetVersion = targetVersion;
183
}
184
185
@Override
186
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
187
if ("version".equals(tag.getName()) && isProjectVersion(tag)) {
188
return tag.withValue(tag.getValue().withText(targetVersion));
189
}
190
return super.visitTag(tag, ctx);
191
}
192
193
private boolean isProjectVersion(Xml.Tag tag) {
194
return tag.getParent()
195
.map(parent -> "project".equals(parent.getName()))
196
.orElse(false);
197
}
198
}
199
200
// Apply the visitor
201
UpdateVersionVisitor visitor = new UpdateVersionVisitor("2.0.0");
202
Xml.Document updated = visitor.visit(pomDocument, ctx);
203
```
204
205
### MavenExecutionContextView
206
207
Provides Maven-specific execution context with settings and profile information.
208
209
```java { .api }
210
/**
211
* Maven-specific execution context with settings and profiles
212
*/
213
public class MavenExecutionContextView extends DelegatingExecutionContext;
214
```
215
216
**Key Methods:**
217
218
```java { .api }
219
/**
220
* Get Maven settings from the execution context
221
* @return MavenSettings instance or null if not available
222
*/
223
public @Nullable MavenSettings getSettings();
224
225
/**
226
* Get active Maven profiles
227
* @return Collection of active profile names
228
*/
229
public Collection<String> getActiveProfiles();
230
231
/**
232
* Create a view from an existing execution context
233
* @param ctx Execution context to wrap
234
* @return MavenExecutionContextView
235
*/
236
public static MavenExecutionContextView view(ExecutionContext ctx);
237
```
238
239
**Usage Examples:**
240
241
```java
242
// Configure Maven execution context
243
ExecutionContext ctx = new InMemoryExecutionContext();
244
MavenExecutionContextView mavenCtx = MavenExecutionContextView.view(ctx);
245
246
// Access Maven-specific configuration
247
MavenSettings settings = mavenCtx.getSettings();
248
Collection<String> profiles = mavenCtx.getActiveProfiles();
249
250
// Use in visitor
251
public class SettingsAwareVisitor extends MavenVisitor<ExecutionContext> {
252
@Override
253
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
254
MavenExecutionContextView mavenCtx = MavenExecutionContextView.view(ctx);
255
MavenSettings settings = mavenCtx.getSettings();
256
257
if (settings != null) {
258
// Use settings information for transformation logic
259
}
260
261
return super.visitDocument(document, ctx);
262
}
263
}
264
```
265
266
### XPath Matchers
267
268
Pre-defined XPath matchers for common Maven POM elements.
269
270
```java
271
// XPath matchers available in MavenVisitor
272
protected static final String DEPENDENCY_MATCHER = "//dependencies/dependency";
273
protected static final String PLUGIN_MATCHER = "//plugins/plugin";
274
protected static final String PROPERTY_MATCHER = "//properties/*";
275
```
276
277
### Error Handling
278
279
Exception types for Maven parsing and processing errors.
280
281
```java { .api }
282
/**
283
* Exception thrown when Maven artifact downloading fails
284
*/
285
public class MavenDownloadingException extends Exception;
286
287
/**
288
* Container for multiple Maven downloading exceptions
289
*/
290
public class MavenDownloadingExceptions extends Exception {
291
/**
292
* Get all contained exceptions
293
* @return List of individual downloading exceptions
294
*/
295
public List<MavenDownloadingException> getExceptions();
296
}
297
```
298
299
**Usage Examples:**
300
301
```java
302
try {
303
MavenParser parser = MavenParser.builder().build();
304
List<SourceFile> parsed = parser.parse(ctx, pomContent);
305
} catch (MavenDownloadingException e) {
306
System.err.println("Failed to download artifact: " + e.getMessage());
307
} catch (MavenDownloadingExceptions e) {
308
System.err.println("Multiple download failures:");
309
for (MavenDownloadingException exception : e.getExceptions()) {
310
System.err.println(" - " + exception.getMessage());
311
}
312
}
313
```