1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin;
20
21 import javax.inject.Named;
22 import javax.inject.Singleton;
23
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Objects;
28 import java.util.concurrent.ConcurrentHashMap;
29
30 import org.apache.maven.RepositoryUtils;
31 import org.apache.maven.model.Plugin;
32 import org.apache.maven.plugin.descriptor.PluginDescriptor;
33 import org.eclipse.aether.RepositorySystemSession;
34 import org.eclipse.aether.repository.LocalRepository;
35 import org.eclipse.aether.repository.RemoteRepository;
36 import org.eclipse.aether.repository.WorkspaceRepository;
37
38
39
40
41
42
43
44
45
46
47 @Named
48 @Singleton
49 public class DefaultPluginDescriptorCache implements PluginDescriptorCache {
50
51 private Map<Key, PluginDescriptor> descriptors = new ConcurrentHashMap<>(128);
52
53 public void flush() {
54 descriptors.clear();
55 }
56
57 public Key createKey(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session) {
58 return new CacheKey(plugin, repositories, session);
59 }
60
61 public PluginDescriptor get(Key cacheKey) {
62 return clone(descriptors.get(cacheKey));
63 }
64
65 @Override
66 public PluginDescriptor get(Key key, PluginDescriptorSupplier supplier)
67 throws PluginDescriptorParsingException, PluginResolutionException, InvalidPluginDescriptorException {
68 try {
69 return clone(descriptors.computeIfAbsent(key, k -> {
70 try {
71 return clone(supplier.load());
72 } catch (PluginDescriptorParsingException
73 | PluginResolutionException
74 | InvalidPluginDescriptorException e) {
75 throw new RuntimeException(e);
76 }
77 }));
78 } catch (RuntimeException e) {
79 if (e.getCause() instanceof PluginDescriptorParsingException) {
80 throw (PluginDescriptorParsingException) e.getCause();
81 }
82 if (e.getCause() instanceof PluginResolutionException) {
83 throw (PluginResolutionException) e.getCause();
84 }
85 if (e.getCause() instanceof InvalidPluginDescriptorException) {
86 throw (InvalidPluginDescriptorException) e.getCause();
87 }
88 throw e;
89 }
90 }
91
92 public void put(Key cacheKey, PluginDescriptor pluginDescriptor) {
93 descriptors.put(cacheKey, clone(pluginDescriptor));
94 }
95
96 protected static PluginDescriptor clone(PluginDescriptor original) {
97 return new PluginDescriptor(original);
98 }
99
100 private static final class CacheKey implements Key {
101
102 private final String groupId;
103
104 private final String artifactId;
105
106 private final String version;
107
108 private final WorkspaceRepository workspace;
109
110 private final LocalRepository localRepo;
111
112 private final List<RemoteRepository> repositories;
113
114 private final int hashCode;
115
116 CacheKey(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session) {
117 groupId = plugin.getGroupId();
118 artifactId = plugin.getArtifactId();
119 version = plugin.getVersion();
120
121 workspace = RepositoryUtils.getWorkspace(session);
122 localRepo = session.getLocalRepository();
123 this.repositories = new ArrayList<>(repositories.size());
124 for (RemoteRepository repository : repositories) {
125 if (repository.isRepositoryManager()) {
126 this.repositories.addAll(repository.getMirroredRepositories());
127 } else {
128 this.repositories.add(repository);
129 }
130 }
131
132 int hash = 17;
133 hash = hash * 31 + groupId.hashCode();
134 hash = hash * 31 + artifactId.hashCode();
135 hash = hash * 31 + version.hashCode();
136 hash = hash * 31 + hash(workspace);
137 hash = hash * 31 + localRepo.hashCode();
138 hash = hash * 31 + RepositoryUtils.repositoriesHashCode(repositories);
139 this.hashCode = hash;
140 }
141
142 @Override
143 public int hashCode() {
144 return hashCode;
145 }
146
147 @Override
148 public boolean equals(Object obj) {
149 if (this == obj) {
150 return true;
151 }
152
153 if (!(obj instanceof CacheKey)) {
154 return false;
155 }
156
157 CacheKey that = (CacheKey) obj;
158
159 return Objects.equals(this.artifactId, that.artifactId)
160 && Objects.equals(this.groupId, that.groupId)
161 && Objects.equals(this.version, that.version)
162 && Objects.equals(this.localRepo, that.localRepo)
163 && Objects.equals(this.workspace, that.workspace)
164 && RepositoryUtils.repositoriesEquals(this.repositories, that.repositories);
165 }
166
167 @Override
168 public String toString() {
169 return groupId + ':' + artifactId + ':' + version;
170 }
171
172 private static int hash(Object obj) {
173 return obj != null ? obj.hashCode() : 0;
174 }
175 }
176 }