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