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.plugin;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Objects;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  import org.apache.maven.RepositoryUtils;
29  import org.apache.maven.artifact.Artifact;
30  import org.apache.maven.model.Plugin;
31  import org.apache.maven.project.MavenProject;
32  import org.codehaus.plexus.component.annotations.Component;
33  import org.eclipse.aether.RepositorySystemSession;
34  import org.eclipse.aether.graph.DependencyFilter;
35  import org.eclipse.aether.repository.LocalRepository;
36  import org.eclipse.aether.repository.RemoteRepository;
37  import org.eclipse.aether.repository.WorkspaceRepository;
38  
39  /**
40   * @author Igor Fedorenko
41   * @author Benjamin Bentmann
42   */
43  @Component(role = PluginArtifactsCache.class)
44  public class DefaultPluginArtifactsCache implements PluginArtifactsCache {
45      /**
46       * CacheKey
47       */
48      protected static class CacheKey implements Key {
49          private final Plugin plugin;
50  
51          private final WorkspaceRepository workspace;
52  
53          private final LocalRepository localRepo;
54  
55          private final List<RemoteRepository> repositories;
56  
57          private final DependencyFilter filter;
58  
59          private final int hashCode;
60  
61          public CacheKey(
62                  Plugin plugin,
63                  DependencyFilter extensionFilter,
64                  List<RemoteRepository> repositories,
65                  RepositorySystemSession session) {
66              this.plugin = plugin.clone();
67              workspace = RepositoryUtils.getWorkspace(session);
68              this.localRepo = session.getLocalRepository();
69              this.repositories = new ArrayList<>(repositories.size());
70              for (RemoteRepository repository : repositories) {
71                  if (repository.isRepositoryManager()) {
72                      this.repositories.addAll(repository.getMirroredRepositories());
73                  } else {
74                      this.repositories.add(repository);
75                  }
76              }
77              this.filter = extensionFilter;
78  
79              int hash = 17;
80              hash = hash * 31 + CacheUtils.pluginHashCode(plugin);
81              hash = hash * 31 + Objects.hashCode(workspace);
82              hash = hash * 31 + Objects.hashCode(localRepo);
83              hash = hash * 31 + RepositoryUtils.repositoriesHashCode(repositories);
84              hash = hash * 31 + Objects.hashCode(extensionFilter);
85              this.hashCode = hash;
86          }
87  
88          @Override
89          public String toString() {
90              return plugin.getId();
91          }
92  
93          @Override
94          public int hashCode() {
95              return hashCode;
96          }
97  
98          @Override
99          public boolean equals(Object o) {
100             if (o == this) {
101                 return true;
102             }
103 
104             if (!(o instanceof CacheKey)) {
105                 return false;
106             }
107 
108             CacheKey that = (CacheKey) o;
109 
110             return CacheUtils.pluginEquals(plugin, that.plugin)
111                     && Objects.equals(workspace, that.workspace)
112                     && Objects.equals(localRepo, that.localRepo)
113                     && RepositoryUtils.repositoriesEquals(repositories, that.repositories)
114                     && Objects.equals(filter, that.filter);
115         }
116     }
117 
118     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
119 
120     public Key createKey(
121             Plugin plugin,
122             DependencyFilter extensionFilter,
123             List<RemoteRepository> repositories,
124             RepositorySystemSession session) {
125         return new CacheKey(plugin, extensionFilter, repositories, session);
126     }
127 
128     public CacheRecord get(Key key) throws PluginResolutionException {
129         CacheRecord cacheRecord = cache.get(key);
130 
131         if (cacheRecord != null && cacheRecord.getException() != null) {
132             throw cacheRecord.getException();
133         }
134 
135         return cacheRecord;
136     }
137 
138     public CacheRecord put(Key key, List<Artifact> pluginArtifacts) {
139         Objects.requireNonNull(pluginArtifacts, "pluginArtifacts cannot be null");
140 
141         assertUniqueKey(key);
142 
143         CacheRecord record = new CacheRecord(Collections.unmodifiableList(new ArrayList<>(pluginArtifacts)));
144 
145         cache.put(key, record);
146 
147         return record;
148     }
149 
150     protected void assertUniqueKey(Key key) {
151         if (cache.containsKey(key)) {
152             throw new IllegalStateException("Duplicate artifact resolution result for plugin " + key);
153         }
154     }
155 
156     public CacheRecord put(Key key, PluginResolutionException exception) {
157         Objects.requireNonNull(exception, "exception cannot be null");
158 
159         assertUniqueKey(key);
160 
161         CacheRecord record = new CacheRecord(exception);
162 
163         cache.put(key, record);
164 
165         return record;
166     }
167 
168     public void flush() {
169         cache.clear();
170     }
171 
172     protected static int pluginHashCode(Plugin plugin) {
173         return CacheUtils.pluginHashCode(plugin);
174     }
175 
176     protected static boolean pluginEquals(Plugin a, Plugin b) {
177         return CacheUtils.pluginEquals(a, b);
178     }
179 
180     public void register(MavenProject project, Key cacheKey, CacheRecord record) {
181         // default cache does not track record usage
182     }
183 }