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.concurrent.ConcurrentHashMap;
27
28 import org.apache.commons.lang3.Validate;
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
47 implements PluginRealmCache, Disposable
48 {
49
50 protected static class CacheKey
51 implements Key
52 {
53
54 private final Plugin plugin;
55
56 private final WorkspaceRepository workspace;
57
58 private final LocalRepository localRepo;
59
60 private final List<RemoteRepository> repositories;
61
62 private final ClassLoader parentRealm;
63
64 private final Map<String, ClassLoader> foreignImports;
65
66 private final DependencyFilter filter;
67
68 private final int hashCode;
69
70 public CacheKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
71 DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
72 RepositorySystemSession session )
73 {
74 this.plugin = plugin.clone();
75 this.workspace = CacheUtils.getWorkspace( session );
76 this.localRepo = session.getLocalRepository();
77 this.repositories = new ArrayList<>( repositories.size() );
78 for ( RemoteRepository repository : repositories )
79 {
80 if ( repository.isRepositoryManager() )
81 {
82 this.repositories.addAll( repository.getMirroredRepositories() );
83 }
84 else
85 {
86 this.repositories.add( repository );
87 }
88 }
89 this.parentRealm = parentRealm;
90 this.foreignImports =
91 ( foreignImports != null ) ? foreignImports : Collections.<String, ClassLoader>emptyMap();
92 this.filter = dependencyFilter;
93
94 int hash = 17;
95 hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
96 hash = hash * 31 + hash( workspace );
97 hash = hash * 31 + hash( localRepo );
98 hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
99 hash = hash * 31 + hash( parentRealm );
100 hash = hash * 31 + this.foreignImports.hashCode();
101 hash = hash * 31 + hash( dependencyFilter );
102 this.hashCode = hash;
103 }
104
105 @Override
106 public String toString()
107 {
108 return plugin.getId();
109 }
110
111 @Override
112 public int hashCode()
113 {
114 return hashCode;
115 }
116
117 private static int hash( Object obj )
118 {
119 return obj != null ? obj.hashCode() : 0;
120 }
121
122 @Override
123 public boolean equals( Object o )
124 {
125 if ( o == this )
126 {
127 return true;
128 }
129
130 if ( !( o instanceof CacheKey ) )
131 {
132 return false;
133 }
134
135 CacheKey that = (CacheKey) o;
136
137 return parentRealm == that.parentRealm && CacheUtils.pluginEquals( plugin, that.plugin )
138 && eq( workspace, that.workspace ) && eq( localRepo, that.localRepo )
139 && CacheUtils.repositoriesEquals( this.repositories, that.repositories ) && eq( filter, that.filter )
140 && eq( foreignImports, that.foreignImports );
141 }
142
143 private static <T> boolean eq( T s1, T s2 )
144 {
145 return s1 != null ? s1.equals( s2 ) : s2 == null;
146 }
147
148 }
149
150 protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
151
152 public Key createKey( Plugin plugin, ClassLoader parentRealm, Map<String, ClassLoader> foreignImports,
153 DependencyFilter dependencyFilter, List<RemoteRepository> repositories,
154 RepositorySystemSession session )
155 {
156 return new CacheKey( plugin, parentRealm, foreignImports, dependencyFilter, repositories, session );
157 }
158
159 public CacheRecord get( Key key )
160 {
161 return cache.get( key );
162 }
163
164 public CacheRecord put( Key key, ClassRealm pluginRealm, List<Artifact> pluginArtifacts )
165 {
166 Validate.notNull( pluginRealm, "pluginRealm cannot be null" );
167 Validate.notNull( pluginArtifacts, "pluginArtifacts cannot be null" );
168
169 if ( cache.containsKey( key ) )
170 {
171 throw new IllegalStateException( "Duplicate plugin realm for plugin " + key );
172 }
173
174 CacheRecord record = new CacheRecord( pluginRealm, pluginArtifacts );
175
176 cache.put( key, record );
177
178 return record;
179 }
180
181 public void flush()
182 {
183 for ( CacheRecord record : cache.values() )
184 {
185 ClassRealm realm = record.realm;
186 try
187 {
188 realm.getWorld().disposeRealm( realm.getId() );
189 }
190 catch ( NoSuchRealmException e )
191 {
192
193 }
194 }
195 cache.clear();
196 }
197
198 protected static int pluginHashCode( Plugin plugin )
199 {
200 return CacheUtils.pluginHashCode( plugin );
201 }
202
203 protected static boolean pluginEquals( Plugin a, Plugin b )
204 {
205 return CacheUtils.pluginEquals( a, b );
206 }
207
208 public void register( MavenProject project, Key key, CacheRecord record )
209 {
210
211 }
212
213 public void dispose()
214 {
215 flush();
216 }
217
218 }