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