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 javax.inject.Named;
30  import javax.inject.Singleton;
31  
32  import org.apache.maven.RepositoryUtils;
33  import org.apache.maven.artifact.Artifact;
34  import org.apache.maven.model.Plugin;
35  import org.apache.maven.project.MavenProject;
36  import org.eclipse.aether.RepositorySystemSession;
37  import org.eclipse.aether.graph.DependencyFilter;
38  import org.eclipse.aether.repository.LocalRepository;
39  import org.eclipse.aether.repository.RemoteRepository;
40  import org.eclipse.aether.repository.WorkspaceRepository;
41  
42  /**
43   * @author Igor Fedorenko
44   * @author Benjamin Bentmann
45   */
46  @Named
47  @Singleton
48  public class DefaultPluginArtifactsCache
49      implements PluginArtifactsCache
50  {
51      /**
52       * CacheKey
53       */
54      protected static class CacheKey
55          implements Key
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 DependencyFilter filter;
66  
67          private final int hashCode;
68  
69          public CacheKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
70                           RepositorySystemSession session )
71          {
72              this.plugin = plugin.clone();
73              workspace = RepositoryUtils.getWorkspace( session );
74              this.localRepo = session.getLocalRepository();
75              this.repositories = new ArrayList<>( repositories.size() );
76              for ( RemoteRepository repository : repositories )
77              {
78                  if ( repository.isRepositoryManager() )
79                  {
80                      this.repositories.addAll( repository.getMirroredRepositories() );
81                  }
82                  else
83                  {
84                      this.repositories.add( repository );
85                  }
86              }
87              this.filter = extensionFilter;
88  
89              int hash = 17;
90              hash = hash * 31 + CacheUtils.pluginHashCode( plugin );
91              hash = hash * 31 + Objects.hashCode( workspace );
92              hash = hash * 31 + Objects.hashCode( localRepo );
93              hash = hash * 31 + RepositoryUtils.repositoriesHashCode( repositories );
94              hash = hash * 31 + Objects.hashCode( extensionFilter );
95              this.hashCode = hash;
96          }
97  
98          @Override
99          public String toString()
100         {
101             return plugin.getId();
102         }
103 
104         @Override
105         public int hashCode()
106         {
107             return hashCode;
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 )
126                 && Objects.equals( workspace, that.workspace )
127                 && Objects.equals( localRepo, that.localRepo )
128                 && RepositoryUtils.repositoriesEquals( repositories, that.repositories )
129                 && Objects.equals( filter, that.filter );
130         }
131     }
132 
133     protected final Map<Key, CacheRecord> cache = new ConcurrentHashMap<>();
134 
135     public Key createKey( Plugin plugin, DependencyFilter extensionFilter, List<RemoteRepository> repositories,
136                           RepositorySystemSession session )
137     {
138         return new CacheKey( plugin, extensionFilter, repositories, session );
139     }
140 
141     public CacheRecord get( Key key )
142         throws PluginResolutionException
143     {
144         CacheRecord cacheRecord = cache.get( key );
145 
146         if ( cacheRecord != null && cacheRecord.getException() != null )
147         {
148             throw cacheRecord.getException();
149         }
150 
151         return cacheRecord;
152     }
153 
154     public CacheRecord put( Key key, List<Artifact> pluginArtifacts )
155     {
156         Objects.requireNonNull( pluginArtifacts, "pluginArtifacts cannot be null" );
157 
158         assertUniqueKey( key );
159 
160         CacheRecord record =
161             new CacheRecord( Collections.unmodifiableList( new ArrayList<>( pluginArtifacts ) ) );
162 
163         cache.put( key, record );
164 
165         return record;
166     }
167 
168     protected void assertUniqueKey( Key key )
169     {
170         if ( cache.containsKey( key ) )
171         {
172             throw new IllegalStateException( "Duplicate artifact resolution result for plugin " + key );
173         }
174     }
175 
176     public CacheRecord put( Key key, PluginResolutionException exception )
177     {
178         Objects.requireNonNull( exception, "exception cannot be null" );
179 
180         assertUniqueKey( key );
181 
182         CacheRecord record = new CacheRecord( exception );
183 
184         cache.put( key, record );
185 
186         return record;
187     }
188 
189     public void flush()
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 cacheKey, CacheRecord record )
205     {
206         // default cache does not track record usage
207     }
208 
209 }