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.artifact.ArtifactUtils;
32 import org.apache.maven.model.Plugin;
33 import org.apache.maven.plugin.descriptor.MojoDescriptor;
34 import org.apache.maven.plugin.descriptor.PluginDescriptor;
35 import org.codehaus.plexus.component.repository.ComponentDescriptor;
36 import org.eclipse.aether.RepositorySystemSession;
37 import org.eclipse.aether.repository.LocalRepository;
38 import org.eclipse.aether.repository.RemoteRepository;
39 import org.eclipse.aether.repository.WorkspaceRepository;
40
41
42
43
44
45
46
47
48
49
50
51 @Named
52 @Singleton
53 public class DefaultPluginDescriptorCache implements PluginDescriptorCache {
54
55 private Map<Key, PluginDescriptor> descriptors = new ConcurrentHashMap<>(128);
56
57 public void flush() {
58 descriptors.clear();
59 }
60
61 public Key createKey(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session) {
62 return new CacheKey(plugin, repositories, session);
63 }
64
65 public PluginDescriptor get(Key cacheKey) {
66 return clone(descriptors.get(cacheKey));
67 }
68
69 @Override
70 public PluginDescriptor get(Key key, PluginDescriptorSupplier supplier)
71 throws PluginDescriptorParsingException, PluginResolutionException, InvalidPluginDescriptorException {
72 try {
73 return clone(descriptors.computeIfAbsent(key, k -> {
74 try {
75 return clone(supplier.load());
76 } catch (PluginDescriptorParsingException
77 | PluginResolutionException
78 | InvalidPluginDescriptorException e) {
79 throw new RuntimeException(e);
80 }
81 }));
82 } catch (RuntimeException e) {
83 if (e.getCause() instanceof PluginDescriptorParsingException) {
84 throw (PluginDescriptorParsingException) e.getCause();
85 }
86 if (e.getCause() instanceof PluginResolutionException) {
87 throw (PluginResolutionException) e.getCause();
88 }
89 if (e.getCause() instanceof InvalidPluginDescriptorException) {
90 throw (InvalidPluginDescriptorException) e.getCause();
91 }
92 throw e;
93 }
94 }
95
96 public void put(Key cacheKey, PluginDescriptor pluginDescriptor) {
97 descriptors.put(cacheKey, clone(pluginDescriptor));
98 }
99
100 protected static PluginDescriptor clone(PluginDescriptor original) {
101 PluginDescriptor clone = null;
102
103 if (original != null) {
104 clone = new PluginDescriptor();
105
106 clone.setGroupId(original.getGroupId());
107 clone.setArtifactId(original.getArtifactId());
108 clone.setVersion(original.getVersion());
109 clone.setGoalPrefix(original.getGoalPrefix());
110 clone.setInheritedByDefault(original.isInheritedByDefault());
111
112 clone.setName(original.getName());
113 clone.setDescription(original.getDescription());
114 clone.setRequiredMavenVersion(original.getRequiredMavenVersion());
115 clone.setRequiredJavaVersion(original.getRequiredJavaVersion());
116
117 clone.setPluginArtifact(ArtifactUtils.copyArtifactSafe(original.getPluginArtifact()));
118
119 clone.setComponents(clone(original.getMojos(), clone));
120 clone.setId(original.getId());
121 clone.setIsolatedRealm(original.isIsolatedRealm());
122 clone.setSource(original.getSource());
123
124 clone.setDependencies(original.getDependencies());
125 }
126
127 return clone;
128 }
129
130 private static List<ComponentDescriptor<?>> clone(List<MojoDescriptor> mojos, PluginDescriptor pluginDescriptor) {
131 List<ComponentDescriptor<?>> clones = null;
132
133 if (mojos != null) {
134 clones = new ArrayList<>(mojos.size());
135
136 for (MojoDescriptor mojo : mojos) {
137 MojoDescriptor clone = mojo.clone();
138 clone.setPluginDescriptor(pluginDescriptor);
139 clones.add(clone);
140 }
141 }
142
143 return clones;
144 }
145
146 private static final class CacheKey implements Key {
147
148 private final String groupId;
149
150 private final String artifactId;
151
152 private final String version;
153
154 private final WorkspaceRepository workspace;
155
156 private final LocalRepository localRepo;
157
158 private final List<RemoteRepository> repositories;
159
160 private final int hashCode;
161
162 CacheKey(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session) {
163 groupId = plugin.getGroupId();
164 artifactId = plugin.getArtifactId();
165 version = plugin.getVersion();
166
167 workspace = RepositoryUtils.getWorkspace(session);
168 localRepo = session.getLocalRepository();
169 this.repositories = new ArrayList<>(repositories.size());
170 for (RemoteRepository repository : repositories) {
171 if (repository.isRepositoryManager()) {
172 this.repositories.addAll(repository.getMirroredRepositories());
173 } else {
174 this.repositories.add(repository);
175 }
176 }
177
178 int hash = 17;
179 hash = hash * 31 + groupId.hashCode();
180 hash = hash * 31 + artifactId.hashCode();
181 hash = hash * 31 + version.hashCode();
182 hash = hash * 31 + hash(workspace);
183 hash = hash * 31 + localRepo.hashCode();
184 hash = hash * 31 + RepositoryUtils.repositoriesHashCode(repositories);
185 this.hashCode = hash;
186 }
187
188 @Override
189 public int hashCode() {
190 return hashCode;
191 }
192
193 @Override
194 public boolean equals(Object obj) {
195 if (this == obj) {
196 return true;
197 }
198
199 if (!(obj instanceof CacheKey)) {
200 return false;
201 }
202
203 CacheKey that = (CacheKey) obj;
204
205 return Objects.equals(this.artifactId, that.artifactId)
206 && Objects.equals(this.groupId, that.groupId)
207 && Objects.equals(this.version, that.version)
208 && Objects.equals(this.localRepo, that.localRepo)
209 && Objects.equals(this.workspace, that.workspace)
210 && RepositoryUtils.repositoriesEquals(this.repositories, that.repositories);
211 }
212
213 @Override
214 public String toString() {
215 return groupId + ':' + artifactId + ':' + version;
216 }
217
218 private static int hash(Object obj) {
219 return obj != null ? obj.hashCode() : 0;
220 }
221 }
222 }