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  
24  import org.apache.maven.model.transform.pull.NodeBufferingParser;
25  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
26  
27  /**
28   * Will apply the version if the dependency is part of the reactor
29   *
30   * @author Robert Scholte
31   * @author Guillaume Nodet
32   * @since 4.0.0
33   */
34  public class ReactorDependencyXMLFilter extends NodeBufferingParser {
35      private final BiFunction<String, String, String> reactorVersionMapper;
36  
37      public ReactorDependencyXMLFilter(
38              XmlPullParser xmlPullParser, BiFunction<String, String, String> reactorVersionMapper) {
39          super(xmlPullParser, "dependency");
40          this.reactorVersionMapper = reactorVersionMapper;
41      }
42  
43      protected void process(List<Event> buffer) {
44          // whiteSpace after <dependency>, to be used to position <version>
45          String dependencyWhitespace = "";
46          boolean hasVersion = false;
47          String groupId = null;
48          String artifactId = null;
49          String tagName = null;
50          for (int i = 0; i < buffer.size(); i++) {
51              Event event = buffer.get(i);
52              if (event.event == START_TAG) {
53                  tagName = event.name;
54                  hasVersion |= "version".equals(tagName);
55              } else if (event.event == TEXT) {
56                  if (event.text.matches("\\s+")) {
57                      if (dependencyWhitespace.isEmpty()) {
58                          dependencyWhitespace = event.text;
59                      }
60                  } else if ("groupId".equals(tagName)) {
61                      groupId = nullSafeAppend(groupId, event.text);
62                  } else if ("artifactId".equals(tagName)) {
63                      artifactId = nullSafeAppend(artifactId, event.text);
64                  }
65              } else if (event.event == END_TAG && "dependency".equals(event.name)) {
66                  String version = reactorVersionMapper.apply(groupId, artifactId);
67                  if (!hasVersion && version != null) {
68                      int pos = buffer.get(i - 1).event == TEXT ? i - 1 : i;
69                      Event e = new Event();
70                      e.event = TEXT;
71                      e.text = dependencyWhitespace;
72                      buffer.add(pos++, e);
73                      e = new Event();
74                      e.event = START_TAG;
75                      e.namespace = buffer.get(0).namespace;
76                      e.prefix = buffer.get(0).prefix;
77                      e.name = "version";
78                      buffer.add(pos++, e);
79                      e = new Event();
80                      e.event = TEXT;
81                      e.text = version;
82                      buffer.add(pos++, e);
83                      e = new Event();
84                      e.event = END_TAG;
85                      e.name = "version";
86                      e.namespace = buffer.get(0).namespace;
87                      e.prefix = buffer.get(0).prefix;
88                      buffer.add(pos++, e);
89                  }
90                  break;
91              }
92          }
93          buffer.forEach(this::pushEvent);
94      }
95  }