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