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