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