1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.model.transform;
20
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.Optional;
27 import java.util.function.Function;
28
29 import org.apache.maven.model.transform.pull.NodeBufferingParser;
30 import org.codehaus.plexus.util.xml.pull.XmlPullParser;
31
32
33
34
35
36
37
38
39
40
41
42
43
44 class ParentXMLFilter extends NodeBufferingParser {
45
46 private final Function<Path, Optional<RelativeProject>> relativePathMapper;
47
48 private final Path projectPath;
49
50
51
52
53 ParentXMLFilter(
54 XmlPullParser parser, Function<Path, Optional<RelativeProject>> relativePathMapper, Path projectPath) {
55 super(parser, "parent");
56 this.relativePathMapper = relativePathMapper;
57 this.projectPath = projectPath;
58 }
59
60 protected void process(List<Event> buffer) {
61 String tagName = null;
62 String groupId = null;
63 String artifactId = null;
64 String version = null;
65 String relativePath = null;
66 String whitespaceAfterParentStart = "";
67 boolean hasVersion = false;
68 boolean hasRelativePath = false;
69 for (int i = 0; i < buffer.size(); i++) {
70 Event event = buffer.get(i);
71 if (event.event == START_TAG) {
72 tagName = event.name;
73 hasVersion |= "version".equals(tagName);
74 hasRelativePath |= "relativePath".equals(tagName);
75 } else if (event.event == TEXT) {
76 if (event.text.matches("\\s+")) {
77 if (whitespaceAfterParentStart.isEmpty()) {
78 whitespaceAfterParentStart = event.text;
79 }
80 } else if ("groupId".equals(tagName)) {
81 groupId = nullSafeAppend(groupId, event.text);
82 } else if ("artifactId".equals(tagName)) {
83 artifactId = nullSafeAppend(artifactId, event.text);
84 } else if ("relativePath".equals(tagName)) {
85 relativePath = nullSafeAppend(relativePath, event.text);
86 } else if ("version".equals(tagName)) {
87 version = nullSafeAppend(version, event.text);
88 }
89 } else if (event.event == END_TAG && "parent".equals(event.name)) {
90 Optional<RelativeProject> resolvedParent;
91 if (!hasVersion && (!hasRelativePath || relativePath != null)) {
92 Path relPath = Paths.get(Objects.toString(relativePath, "../pom.xml"));
93 resolvedParent = resolveRelativePath(relPath, groupId, artifactId);
94 } else {
95 resolvedParent = Optional.empty();
96 }
97 if (!hasVersion && resolvedParent.isPresent()) {
98 int pos = buffer.get(i - 1).event == TEXT ? i - 1 : i;
99 Event e = new Event();
100 e.event = TEXT;
101 e.text = whitespaceAfterParentStart;
102 buffer.add(pos++, e);
103 e = new Event();
104 e.event = START_TAG;
105 e.namespace = buffer.get(0).namespace;
106 e.prefix = buffer.get(0).prefix;
107 e.name = "version";
108 buffer.add(pos++, e);
109 e = new Event();
110 e.event = TEXT;
111 e.text = resolvedParent.get().getVersion();
112 buffer.add(pos++, e);
113 e = new Event();
114 e.event = END_TAG;
115 e.name = "version";
116 e.namespace = buffer.get(0).namespace;
117 e.prefix = buffer.get(0).prefix;
118 buffer.add(pos++, e);
119 }
120 break;
121 }
122 }
123 buffer.forEach(this::pushEvent);
124 }
125
126 protected Optional<RelativeProject> resolveRelativePath(Path relativePath, String groupId, String artifactId) {
127 Path pomPath = projectPath.resolve(relativePath);
128 if (Files.isDirectory(pomPath)) {
129 pomPath = pomPath.resolve("pom.xml");
130 }
131
132 Optional<RelativeProject> mappedProject = relativePathMapper.apply(pomPath.normalize());
133
134 if (mappedProject.isPresent()) {
135 RelativeProject project = mappedProject.get();
136
137 if (Objects.equals(groupId, project.getGroupId()) && Objects.equals(artifactId, project.getArtifactId())) {
138 return mappedProject;
139 }
140 }
141 return Optional.empty();
142 }
143 }