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 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.classworlds.realm.ClassRealm;
33 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
34 import org.codehaus.plexus.component.annotations.Component;
35 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
36 import org.eclipse.aether.RepositorySystemSession;
37 import org.eclipse.aether.graph.DependencyFilter;
38 import org.eclipse.aether.repository.LocalRepository;
39 import org.eclipse.aether.repository.RemoteRepository;
40 import org.eclipse.aether.repository.WorkspaceRepository;
41
42
43
44
45 @Component(role = PluginRealmCache.class)
46 public class DefaultPluginRealmCache implements PluginRealmCache, Disposable {
47
48
49
50 protected static class CacheKey implements Key {
51
52 private final Plugin plugin;
53
54 private final WorkspaceRepository workspace;
55
56 private final LocalRepository localRepo;
57
58 private final List<RemoteRepository> repositories;
59
60 private final ClassLoader parentRealm;
61
62 private final Map<String, ClassLoader> foreignImports;
63
64 private final DependencyFilter filter;
65
66 private final int hashCode;
67
68 public CacheKey(
69 Plugin plugin,
70 ClassLoader parentRealm,
71 Map<String, ClassLoader> foreignImports,
72 DependencyFilter dependencyFilter,
73 List<RemoteRepository> repositories,
74 RepositorySystemSession session) {
75 this.plugin = plugin.clone();
76 this.workspace = RepositoryUtils.getWorkspace(session);
77 this.localRepo = session.getLocalRepository();
78 this.repositories = new ArrayList<>(repositories.size());
79 for (RemoteRepository repository : repositories) {
80 if (repository.isRepositoryManager()) {
81 this.repositories.addAll(repository.getMirroredRepositories());
82 } else {
83 this.repositories.add(repository);
84 }
85 }
86 this.parentRealm = parentRealm;
87 this.foreignImports =
88 (foreignImports != null) ? foreignImports : Collections.<String, ClassLoader>emptyMap();
89 this.filter = dependencyFilter;
90
91 int hash = 17;
92 hash = hash * 31 + CacheUtils.pluginHashCode(plugin);
93 hash = hash * 31 + Objects.hashCode(workspace);
94 hash = hash * 31 + Objects.hashCode(localRepo);
95 hash = hash * 31 + RepositoryUtils.repositoriesHashCode(repositories);
96 hash = hash * 31 + Objects.hashCode(parentRealm);
97 hash = hash * 31 + this.foreignImports.hashCode();
98 hash = hash * 31 + Objects.hashCode(dependencyFilter);
99 this.hashCode = hash;
100 }
101
102 @Override
103 public String toString() {
104 return plugin.getId();
105 }
106
107 @Override
108 public int hashCode() {
109 return hashCode;
110 }
111
112 @Override
113 public boolean equals(Object o) {
114 if (o == this) {
115 return true;
116 }
117
118 if (!(o instanceof CacheKey)) {
119 return false;
120 }
121
122 CacheKey that = (CacheKey) o;
123
124 return parentRealm == that.parentRealm
125 && CacheUtils.pluginEquals(plugin, that.plugin)
126 && Objects.equals(workspace, that.workspace)
127 && Objects.equals(localRepo, that.localRepo)
128 && RepositoryUtils.repositoriesEquals(this.repositories, that.repositories)
129 && Objects.equals(filter, that.filter)
130 && Objects.equals(foreignImports, that.foreignImports);
131 }
132 }
133
134 protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
135
136 public Key createKey(
137 Plugin plugin,
138 ClassLoader parentRealm,
139 Map<String, ClassLoader> foreignImports,
140 DependencyFilter dependencyFilter,
141 List<RemoteRepository> repositories,
142 RepositorySystemSession session) {
143 return new CacheKey(plugin, parentRealm, foreignImports, dependencyFilter, repositories, session);
144 }
145
146 public CacheRecord get(Key key) {
147 return cache.get(key);
148 }
149
150 public CacheRecord put(Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts) {
151 Objects.requireNonNull(pluginRealm, "pluginRealm cannot be null");
152 Objects.requireNonNull(pluginArtifacts, "pluginArtifacts cannot be null");
153
154 if (cache.containsKey(key)) {
155 throw new IllegalStateException("Duplicate plugin realm for plugin " + key);
156 }
157
158 CacheRecord record = new CacheRecord(pluginRealm, pluginArtifacts);
159
160 cache.put(key, record);
161
162 return record;
163 }
164
165 public void flush() {
166 for (CacheRecord record : cache.values()) {
167 ClassRealm realm = record.getRealm();
168 try {
169 realm.getWorld().disposeRealm(realm.getId());
170 } catch (NoSuchRealmException e) {
171
172 }
173 }
174 cache.clear();
175 }
176
177 protected static int pluginHashCode(Plugin plugin) {
178 return CacheUtils.pluginHashCode(plugin);
179 }
180
181 protected static boolean pluginEquals(Plugin a, Plugin b) {
182 return CacheUtils.pluginEquals(a, b);
183 }
184
185 public void register(MavenProject project, Key key, CacheRecord record) {
186
187 }
188
189 public void dispose() {
190 flush();
191 }
192 }