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