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.resolver;
20  
21  import java.util.HashSet;
22  import java.util.List;
23  import java.util.Set;
24  import java.util.stream.Collectors;
25  
26  import org.apache.maven.api.RemoteRepository;
27  import org.apache.maven.api.Session;
28  import org.apache.maven.api.model.Repository;
29  import org.apache.maven.api.services.ModelRepositoryHolder;
30  import org.apache.maven.api.services.RepositoryFactory;
31  
32  public class DefaultModelRepositoryHolder implements ModelRepositoryHolder {
33  
34      /**
35       * The possible merge modes for combining remote repositories.
36       */
37      public enum RepositoryMerging {
38  
39          /**
40           * The repositories declared in the POM have precedence over the repositories specified in the request.
41           */
42          POM_DOMINANT,
43  
44          /**
45           * The repositories specified in the request have precedence over the repositories declared in the POM.
46           */
47          REQUEST_DOMINANT,
48      }
49  
50      final Session session;
51      final RepositoryMerging repositoryMerging;
52  
53      List<RemoteRepository> pomRepositories;
54      List<RemoteRepository> repositories;
55      List<RemoteRepository> externalRepositories;
56      Set<String> ids;
57  
58      public DefaultModelRepositoryHolder(
59              Session session, RepositoryMerging repositoryMerging, List<RemoteRepository> externalRepositories) {
60          this.session = session;
61          this.repositoryMerging = repositoryMerging;
62          this.pomRepositories = List.of();
63          this.externalRepositories = List.copyOf(externalRepositories);
64          this.repositories = List.copyOf(externalRepositories);
65          this.ids = new HashSet<>();
66      }
67  
68      protected DefaultModelRepositoryHolder(DefaultModelRepositoryHolder holder) {
69          this.session = holder.session;
70          this.repositoryMerging = holder.repositoryMerging;
71          this.pomRepositories = List.copyOf(holder.pomRepositories);
72          this.externalRepositories = List.copyOf(holder.externalRepositories);
73          this.repositories = List.copyOf(holder.repositories);
74      }
75  
76      @Override
77      public void merge(List<Repository> toAdd, boolean replace) {
78          List<RemoteRepository> repos =
79                  toAdd.stream().map(session::createRemoteRepository).toList();
80          if (replace) {
81              Set<String> ids = repos.stream().map(RemoteRepository::getId).collect(Collectors.toSet());
82              repositories =
83                      repositories.stream().filter(r -> !ids.contains(r.getId())).toList();
84              pomRepositories = pomRepositories.stream()
85                      .filter(r -> !ids.contains(r.getId()))
86                      .toList();
87          } else {
88              Set<String> ids =
89                      pomRepositories.stream().map(RemoteRepository::getId).collect(Collectors.toSet());
90              repos = repos.stream().filter(r -> !ids.contains(r.getId())).toList();
91          }
92  
93          RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class);
94          if (repositoryMerging == RepositoryMerging.REQUEST_DOMINANT) {
95              repositories = repositoryFactory.aggregate(session, repositories, repos, true);
96              pomRepositories = repositories;
97          } else {
98              pomRepositories = repositoryFactory.aggregate(session, pomRepositories, repos, true);
99              repositories = repositoryFactory.aggregate(session, pomRepositories, externalRepositories, false);
100         }
101     }
102 
103     @Override
104     public List<org.apache.maven.api.RemoteRepository> getRepositories() {
105         return List.copyOf(repositories);
106     }
107 
108     @Override
109     public ModelRepositoryHolder copy() {
110         return new DefaultModelRepositoryHolder(this);
111     }
112 }