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.internal.impl;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.Objects;
24  import java.util.Optional;
25  
26  import org.apache.maven.api.Artifact;
27  import org.apache.maven.api.Dependency;
28  import org.apache.maven.api.Node;
29  import org.apache.maven.api.RemoteRepository;
30  import org.apache.maven.api.annotations.Nonnull;
31  import org.eclipse.aether.graph.DependencyNode;
32  import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
33  import org.eclipse.aether.util.graph.transformer.ConflictResolver;
34  
35  public class DefaultNode extends AbstractNode {
36  
37      protected final @Nonnull InternalSession session;
38      protected final @Nonnull org.eclipse.aether.graph.DependencyNode node;
39      protected final boolean verbose;
40  
41      public DefaultNode(
42              @Nonnull InternalSession session, @Nonnull org.eclipse.aether.graph.DependencyNode node, boolean verbose) {
43          this.session = session;
44          this.node = node;
45          this.verbose = verbose;
46      }
47  
48      @Override
49      DependencyNode getDependencyNode() {
50          return node;
51      }
52  
53      @Override
54      public Artifact getArtifact() {
55          return node.getArtifact() != null ? session.getArtifact(node.getArtifact()) : null;
56      }
57  
58      @Override
59      public Dependency getDependency() {
60          return node.getDependency() != null ? session.getDependency(node.getDependency()) : null;
61      }
62  
63      @Override
64      public List<Node> getChildren() {
65          return new MappedList<>(node.getChildren(), n -> session.getNode(n, verbose));
66      }
67  
68      @Override
69      public List<RemoteRepository> getRemoteRepositories() {
70          return new MappedList<>(node.getRepositories(), session::getRemoteRepository);
71      }
72  
73      @Override
74      public Optional<RemoteRepository> getRepository() {
75          // TODO: v4: implement
76          throw new UnsupportedOperationException("Not implemented yet");
77      }
78  
79      @Override
80      public String asString() {
81          String nodeString = super.asString();
82  
83          if (!verbose) {
84              return nodeString;
85          }
86  
87          org.eclipse.aether.graph.DependencyNode node = getDependencyNode();
88  
89          List<String> details = new ArrayList<>();
90  
91          org.eclipse.aether.graph.DependencyNode winner =
92                  (org.eclipse.aether.graph.DependencyNode) node.getData().get(ConflictResolver.NODE_DATA_WINNER);
93          String winnerVersion = winner != null ? winner.getArtifact().getBaseVersion() : null;
94          boolean included = (winnerVersion == null);
95  
96          String preManagedVersion = DependencyManagerUtils.getPremanagedVersion(node);
97          if (preManagedVersion != null) {
98              details.add("version managed from " + preManagedVersion);
99          }
100 
101         String preManagedScope = DependencyManagerUtils.getPremanagedScope(node);
102         if (preManagedScope != null) {
103             details.add("scope managed from " + preManagedScope);
104         }
105 
106         String originalScope = (String) node.getData().get(ConflictResolver.NODE_DATA_ORIGINAL_SCOPE);
107         if (originalScope != null && !originalScope.equals(node.getDependency().getScope())) {
108             details.add("scope updated from " + originalScope);
109         }
110 
111         if (!included) {
112             if (Objects.equals(winnerVersion, node.getArtifact().getVersion())) {
113                 details.add("omitted for duplicate");
114             } else {
115                 details.add("omitted for conflict with " + winnerVersion);
116             }
117         }
118 
119         StringBuilder buffer = new StringBuilder();
120         if (included) {
121             buffer.append(nodeString);
122             if (!details.isEmpty()) {
123                 buffer.append(" (");
124                 join(buffer, details, "; ");
125                 buffer.append(")");
126             }
127         } else {
128             buffer.append("(");
129             buffer.append(nodeString);
130             if (!details.isEmpty()) {
131                 buffer.append(" - ");
132                 join(buffer, details, "; ");
133             }
134             buffer.append(")");
135         }
136         return buffer.toString();
137     }
138 
139     private static void join(StringBuilder buffer, List<String> details, String separator) {
140         boolean first = true;
141         for (String detail : details) {
142             if (first) {
143                 first = false;
144             } else {
145                 buffer.append(separator);
146             }
147             buffer.append(detail);
148         }
149     }
150 }