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.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.component.annotations.Component;
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   * @author Igor Fedorenko
43   * @author Benjamin Bentmann
44   */
45  @Component( role = PluginArtifactsCache.class )
46  public class DefaultPluginArtifactsCache
47      implements PluginArtifactsCache
48  {
49      /**
50       * CacheKey
51       */
52      protected static class CacheKey
53          implements Key
54      {
55          private final Plugin plugin;
56  
57          private final WorkspaceRepository workspace;
58  
59          private final LocalRepository localRepo;
60  
61          private final List<RemoteRepository> repositories;
62  
63          private final DependencyFilter filter;
64  
65          private final int hashCode;
66  
67          public CacheKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
68                           RepositorySystemSession session )
69          {
70              this.plugin = plugin.clone();
71              workspace = RepositoryUtils.getWorkspace( session );
72              this.localRepo = session.getLocalRepository();
73              this.repositories = new ArrayList<>( repositories.size() );
74              for ( RemoteRepository repository : repositories )
75              {
76                  if ( repository.isRepositoryManager() )
77                  {
78                      this.repositories.addAll( repository.getMirroredRepositories() );
79                  }
80                  else
81                  {
82                      this.repositories.add( repository );
83                  }
84              }
85              this.filter = extensionFilter;
86  
87              int hash = 17;
88              hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
89              hash = hash * 31 + Objects.hashCode( workspace );
90              hash = hash * 31 + Objects.hashCode( localRepo );
91              hash = hash * 31 + RepositoryUtils.repositoriesHashCode( repositories );
92              hash = hash * 31 + Objects.hashCode( extensionFilter );
93              this.hashCode = hash;
94          }
95  
96          @Override
97          public String toString()
98          {
99              return plugin.getId();
100         }
101 
102         @Override
103         public int hashCode()
104         {
105             return hashCode;
106         }
107 
108         @Override
109         public boolean equals( Object o )
110         {
111             if ( o == this )
112             {
113                 return true;
114             }
115 
116             if ( !( o instanceof CacheKey ) )
117             {
118                 return false;
119             }
120 
121             CacheKey that = (CacheKey) o;
122 
123             return CacheUtils.pluginEquals( plugin, that.plugin ) 
124                 && Objects.equals( workspace, that.workspace )
125                 && Objects.equals( localRepo, that.localRepo ) 
126                 && RepositoryUtils.repositoriesEquals( repositories, that.repositories )
127                 && Objects.equals( filter, that.filter );
128         }
129     }
130 
131     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
132 
133     public Key createKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
134                           RepositorySystemSession session )
135     {
136         return new CacheKey( plugin, extensionFilter, repositories, session );
137     }
138 
139     public CacheRecord get( Key key )
140         throws PluginResolutionException
141     {
142         CacheRecord cacheRecord = cache.get( key );
143 
144         if ( cacheRecord != null && cacheRecord.getException() != null )
145         {
146             throw cacheRecord.getException();
147         }
148 
149         return cacheRecord;
150     }
151 
152     public CacheRecord put( Key key, List<Artifact> pluginArtifacts )
153     {
154         Validate.notNull( pluginArtifacts, "pluginArtifacts cannot be null" );
155 
156         assertUniqueKey( key );
157 
158         CacheRecord record =
159             new CacheRecord( Collections.unmodifiableList( new ArrayList<>( pluginArtifacts ) ) );
160 
161         cache.put( key, record );
162 
163         return record;
164     }
165 
166     protected void assertUniqueKey( Key key )
167     {
168         if ( cache.containsKey( key ) )
169         {
170             throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + key );
171         }
172     }
173 
174     public CacheRecord put( Key key, PluginResolutionException exception )
175     {
176         Validate.notNull( exception, "exception cannot be null" );
177 
178         assertUniqueKey( key );
179 
180         CacheRecord record = new CacheRecord( exception );
181 
182         cache.put( key, record );
183 
184         return record;
185     }
186 
187     public void flush()
188     {
189         cache.clear();
190     }
191 
192     protected static int pluginHashCode( Plugin plugin )
193     {
194         return CacheUtils.pluginHashCode( plugin );
195     }
196 
197     protected static boolean pluginEquals( Plugin a, Plugin b )
198     {
199         return CacheUtils.pluginEquals( a, b );
200     }
201 
202     public void register( MavenProject project, Key cacheKey, CacheRecord record )
203     {
204         // default cache does not track record usage
205     }
206 
207 }