View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.model.transform;
20  
21  import java.util.List;
22  import java.util.function.BiFunction;
23  import org.apache.maven.model.transform.pull.NodeBufferingParser;
24  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
25  
26  /**
27   * Will apply the version if the dependency is part of the reactor
28   *
29   * @author Robert Scholte
30   * @author Guillaume Nodet
31   * @since 4.0.0
32   */
33  public class ReactorDependencyXMLFilter extends NodeBufferingParser {
34      private final BiFunction<String, String, String> reactorVersionMapper;
35  
36      public ReactorDependencyXMLFilter(
37              XmlPullParser xmlPullParser, BiFunction<String, String, String> reactorVersionMapper) {
38          super(xmlPullParser, "dependency");
39          this.reactorVersionMapper = reactorVersionMapper;
40      }
41  
42      protected void process(List<Event> buffer) {
43          // whiteSpace after <dependency>, to be used to position <version>
44          String dependencyWhitespace = "";
45          boolean hasVersion = false;
46          String groupId = null;
47          String artifactId = null;
48          String tagName = null;
49          for (int i = 0; i < buffer.size(); i++) {
50              Event event = buffer.get(i);
51              if (event.event == START_TAG) {
52                  tagName = event.name;
53                  hasVersion |= "version".equals(tagName);
54              } else if (event.event == TEXT) {
55                  if (event.text.matches("\\s+")) {
56                      if (dependencyWhitespace.isEmpty()) {
57                          dependencyWhitespace = event.text;
58                      }
59                  } else if ("groupId".equals(tagName)) {
60                      groupId = nullSafeAppend(groupId, event.text);
61                  } else if ("artifactId".equals(tagName)) {
62                      artifactId = nullSafeAppend(artifactId, event.text);
63                  }
64              } else if (event.event == END_TAG && "dependency".equals(event.name)) {
65                  String version = reactorVersionMapper.apply(groupId, artifactId);
66                  if (!hasVersion && version != null) {
67                      int pos = buffer.get(i - 1).event == TEXT ? i - 1 : i;
68                      Event e = new Event();
69                      e.event = TEXT;
70                      e.text = dependencyWhitespace;
71                      buffer.add(pos++, e);
72                      e = new Event();
73                      e.event = START_TAG;
74                      e.namespace = buffer.get(0).namespace;
75                      e.prefix = buffer.get(0).prefix;
76                      e.name = "version";
77                      buffer.add(pos++, e);
78                      e = new Event();
79                      e.event = TEXT;
80                      e.text = version;
81                      buffer.add(pos++, e);
82                      e = new Event();
83                      e.event = END_TAG;
84                      e.name = "version";
85                      e.namespace = buffer.get(0).namespace;
86                      e.prefix = buffer.get(0).prefix;
87                      buffer.add(pos++, e);
88                  }
89                  break;
90              }
91          }
92          buffer.forEach(this::pushEvent);
93      }
94  }