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.composition;
20  
21  import javax.inject.Named;
22  import javax.inject.Singleton;
23  
24  import java.util.Collection;
25  import java.util.HashSet;
26  import java.util.Iterator;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.Objects;
31  import java.util.Set;
32  
33  import org.apache.maven.api.model.Dependency;
34  import org.apache.maven.api.model.DependencyManagement;
35  import org.apache.maven.api.model.Exclusion;
36  import org.apache.maven.api.model.Model;
37  import org.apache.maven.model.building.ModelBuildingRequest;
38  import org.apache.maven.model.building.ModelProblem;
39  import org.apache.maven.model.building.ModelProblemCollector;
40  import org.apache.maven.model.building.ModelProblemCollectorRequest;
41  
42  /**
43   * Handles the import of dependency management from other models into the target model.
44   *
45   * @deprecated use {@link org.apache.maven.api.services.ModelBuilder} instead
46   */
47  @Named
48  @Singleton
49  @Deprecated(since = "4.0.0")
50  public class DefaultDependencyManagementImporter implements DependencyManagementImporter {
51  
52      @Override
53      public Model importManagement(
54              Model target,
55              List<? extends DependencyManagement> sources,
56              ModelBuildingRequest request,
57              ModelProblemCollector problems) {
58          if (sources != null && !sources.isEmpty()) {
59              Map<String, Dependency> dependencies = new LinkedHashMap<>();
60  
61              DependencyManagement depMgmt = target.getDependencyManagement();
62  
63              if (depMgmt != null) {
64                  for (Dependency dependency : depMgmt.getDependencies()) {
65                      dependencies.put(dependency.getManagementKey(), dependency);
66                  }
67              } else {
68                  depMgmt = DependencyManagement.newInstance();
69              }
70  
71              Set<String> directDependencies = new HashSet<>(dependencies.keySet());
72  
73              for (DependencyManagement source : sources) {
74                  for (Dependency dependency : source.getDependencies()) {
75                      String key = dependency.getManagementKey();
76                      Dependency present = dependencies.putIfAbsent(key, dependency);
77                      if (present != null && !equals(dependency, present) && !directDependencies.contains(key)) {
78                          // TODO: https://issues.apache.org/jira/browse/MNG-8004
79                          problems.add(new ModelProblemCollectorRequest(
80                                          ModelProblem.Severity.WARNING, ModelProblem.Version.V40)
81                                  .setMessage("Ignored POM import for: " + toString(dependency) + " as already imported "
82                                          + toString(present) + ". Add the conflicting managed dependency directly "
83                                          + "to the dependencyManagement section of the POM."));
84                      }
85                  }
86              }
87  
88              return target.withDependencyManagement(depMgmt.withDependencies(dependencies.values()));
89          }
90          return target;
91      }
92  
93      private String toString(Dependency dependency) {
94          StringBuilder stringBuilder = new StringBuilder();
95          stringBuilder
96                  .append(dependency.getGroupId())
97                  .append(":")
98                  .append(dependency.getArtifactId())
99                  .append(":")
100                 .append(dependency.getType());
101         if (dependency.getClassifier() != null && !dependency.getClassifier().isEmpty()) {
102             stringBuilder.append(":").append(dependency.getClassifier());
103         }
104         stringBuilder
105                 .append(":")
106                 .append(dependency.getVersion())
107                 .append("@")
108                 .append(dependency.getScope() == null ? "compile" : dependency.getScope());
109         if (dependency.isOptional()) {
110             stringBuilder.append("[optional]");
111         }
112         if (!dependency.getExclusions().isEmpty()) {
113             stringBuilder.append("[").append(dependency.getExclusions().size()).append(" exclusions]");
114         }
115         return stringBuilder.toString();
116     }
117 
118     private boolean equals(Dependency d1, Dependency d2) {
119         return Objects.equals(d1.getGroupId(), d2.getGroupId())
120                 && Objects.equals(d1.getArtifactId(), d2.getArtifactId())
121                 && Objects.equals(d1.getVersion(), d2.getVersion())
122                 && Objects.equals(d1.getType(), d2.getType())
123                 && Objects.equals(d1.getClassifier(), d2.getClassifier())
124                 && Objects.equals(d1.getScope(), d2.getScope())
125                 && Objects.equals(d1.getSystemPath(), d2.getSystemPath())
126                 && Objects.equals(d1.getOptional(), d2.getOptional())
127                 && equals(d1.getExclusions(), d2.getExclusions());
128     }
129 
130     private boolean equals(Collection<Exclusion> ce1, Collection<Exclusion> ce2) {
131         if (ce1.size() == ce2.size()) {
132             Iterator<Exclusion> i1 = ce1.iterator();
133             Iterator<Exclusion> i2 = ce2.iterator();
134             while (i1.hasNext() && i2.hasNext()) {
135                 if (!equals(i1.next(), i2.next())) {
136                     return false;
137                 }
138             }
139             return !i1.hasNext() && !i2.hasNext();
140         }
141         return false;
142     }
143 
144     private boolean equals(Exclusion e1, Exclusion e2) {
145         return Objects.equals(e1.getGroupId(), e2.getGroupId())
146                 && Objects.equals(e1.getArtifactId(), e2.getArtifactId());
147     }
148 }