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