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