View Javadoc
1   package org.apache.maven.plugin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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.component.annotations.Component;
33  import org.eclipse.aether.RepositorySystemSession;
34  import org.eclipse.aether.graph.DependencyFilter;
35  import org.eclipse.aether.repository.LocalRepository;
36  import org.eclipse.aether.repository.RemoteRepository;
37  import org.eclipse.aether.repository.WorkspaceRepository;
38  
39  /**
40   * @author Igor Fedorenko
41   * @author Benjamin Bentmann
42   */
43  @Component( role = PluginArtifactsCache.class )
44  public class DefaultPluginArtifactsCache
45      implements PluginArtifactsCache
46  {
47  
48      protected static class CacheKey
49          implements Key
50      {
51  
52          private final Plugin plugin;
53  
54          private final WorkspaceRepository workspace;
55  
56          private final LocalRepository localRepo;
57  
58          private final List<RemoteRepository> repositories;
59  
60          private final DependencyFilter filter;
61  
62          private final int hashCode;
63  
64          public CacheKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
65                           RepositorySystemSession session )
66          {
67              this.plugin = plugin.clone();
68              workspace = CacheUtils.getWorkspace( session );
69              this.localRepo = session.getLocalRepository();
70              this.repositories = new ArrayList<>( repositories.size() );
71              for ( RemoteRepository repository : repositories )
72              {
73                  if ( repository.isRepositoryManager() )
74                  {
75                      this.repositories.addAll( repository.getMirroredRepositories() );
76                  }
77                  else
78                  {
79                      this.repositories.add( repository );
80                  }
81              }
82              this.filter = extensionFilter;
83  
84              int hash = 17;
85              hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
86              hash = hash * 31 + hash( workspace );
87              hash = hash * 31 + hash( localRepo );
88              hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
89              hash = hash * 31 + hash( extensionFilter );
90              this.hashCode = hash;
91          }
92  
93          @Override
94          public String toString()
95          {
96              return plugin.getId();
97          }
98  
99          @Override
100         public int hashCode()
101         {
102             return hashCode;
103         }
104 
105         private static int hash( Object obj )
106         {
107             return obj != null ? obj.hashCode() : 0;
108         }
109 
110         @Override
111         public boolean equals( Object o )
112         {
113             if ( o == this )
114             {
115                 return true;
116             }
117 
118             if ( !( o instanceof CacheKey ) )
119             {
120                 return false;
121             }
122 
123             CacheKey that = (CacheKey) o;
124 
125             return CacheUtils.pluginEquals( plugin, that.plugin ) && eq( workspace, that.workspace )
126                 && eq( localRepo, that.localRepo ) && CacheUtils.repositoriesEquals( repositories, that.repositories )
127                 && eq( filter, that.filter );
128         }
129 
130         private static <T> boolean eq( T s1, T s2 )
131         {
132             return s1 != null ? s1.equals( s2 ) : s2 == null;
133         }
134 
135     }
136 
137     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
138 
139     public Key createKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
140                           RepositorySystemSession session )
141     {
142         return new CacheKey( plugin, extensionFilter, repositories, session );
143     }
144 
145     public CacheRecord get( Key key )
146         throws PluginResolutionException
147     {
148         CacheRecord cacheRecord = cache.get( key );
149 
150         if ( cacheRecord != null && cacheRecord.exception != null )
151         {
152             throw cacheRecord.exception;
153         }
154 
155         return cacheRecord;
156     }
157 
158     public CacheRecord put( Key key, List<Artifact> pluginArtifacts )
159     {
160         Validate.notNull( pluginArtifacts, "pluginArtifacts cannot be null" );
161 
162         assertUniqueKey( key );
163 
164         CacheRecord record =
165             new CacheRecord( Collections.unmodifiableList( new ArrayList<>( pluginArtifacts ) ) );
166 
167         cache.put( key, record );
168 
169         return record;
170     }
171 
172     protected void assertUniqueKey( Key key )
173     {
174         if ( cache.containsKey( key ) )
175         {
176             throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + key );
177         }
178     }
179 
180     public CacheRecord put( Key key, PluginResolutionException exception )
181     {
182         Validate.notNull( exception, "exception cannot be null" );
183 
184         assertUniqueKey( key );
185 
186         CacheRecord record = new CacheRecord( exception );
187 
188         cache.put( key, record );
189 
190         return record;
191     }
192 
193     public void flush()
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 cacheKey, CacheRecord record )
209     {
210         // default cache does not track record usage
211     }
212 
213 }