001 package org.apache.maven.plugin;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.ArrayList;
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026
027 import org.apache.maven.artifact.ArtifactUtils;
028 import org.apache.maven.model.Plugin;
029 import org.apache.maven.plugin.descriptor.MojoDescriptor;
030 import org.apache.maven.plugin.descriptor.PluginDescriptor;
031 import org.codehaus.plexus.component.annotations.Component;
032 import org.codehaus.plexus.component.repository.ComponentDescriptor;
033 import org.eclipse.aether.RepositorySystemSession;
034 import org.eclipse.aether.repository.LocalRepository;
035 import org.eclipse.aether.repository.RemoteRepository;
036 import org.eclipse.aether.repository.WorkspaceRepository;
037
038 /**
039 * Caches raw plugin descriptors. A raw plugin descriptor is a descriptor that has just been extracted from the plugin
040 * artifact and does not contain any runtime specific data. The cache must not be used for descriptors that hold runtime
041 * data like the plugin realm. <strong>Warning:</strong> This is an internal utility interface that is only public for
042 * technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
043 * prior notice.
044 *
045 * @since 3.0
046 * @author Benjamin Bentmann
047 */
048 @Component( role = PluginDescriptorCache.class )
049 public class DefaultPluginDescriptorCache
050 implements PluginDescriptorCache
051 {
052
053 private Map<Key, PluginDescriptor> descriptors = new HashMap<Key, PluginDescriptor>( 128 );
054
055 public void flush()
056 {
057 descriptors.clear();
058 }
059
060 public Key createKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
061 {
062 return new CacheKey( plugin, repositories, session );
063 }
064
065 public PluginDescriptor get( Key cacheKey )
066 {
067 return clone( descriptors.get( cacheKey ) );
068 }
069
070 public void put( Key cacheKey, PluginDescriptor pluginDescriptor )
071 {
072 descriptors.put( cacheKey, clone( pluginDescriptor ) );
073 }
074
075 protected static PluginDescriptor clone( PluginDescriptor original )
076 {
077 PluginDescriptor clone = null;
078
079 if ( original != null )
080 {
081 clone = new PluginDescriptor();
082
083 clone.setGroupId( original.getGroupId() );
084 clone.setArtifactId( original.getArtifactId() );
085 clone.setVersion( original.getVersion() );
086 clone.setGoalPrefix( original.getGoalPrefix() );
087 clone.setInheritedByDefault( original.isInheritedByDefault() );
088
089 clone.setName( original.getName() );
090 clone.setDescription( original.getDescription() );
091 clone.setRequiredMavenVersion( original.getRequiredMavenVersion() );
092
093 clone.setPluginArtifact( ArtifactUtils.copyArtifactSafe( original.getPluginArtifact() ) );
094
095 clone.setComponents( clone( original.getMojos(), clone ) );
096 clone.setId( original.getId() );
097 clone.setIsolatedRealm( original.isIsolatedRealm() );
098 clone.setSource( original.getSource() );
099
100 clone.setDependencies( original.getDependencies() );
101 }
102
103 return clone;
104 }
105
106 private static List<ComponentDescriptor<?>> clone( List<MojoDescriptor> mojos, PluginDescriptor pluginDescriptor )
107 {
108 List<ComponentDescriptor<?>> clones = null;
109
110 if ( mojos != null )
111 {
112 clones = new ArrayList<ComponentDescriptor<?>>( mojos.size() );
113
114 for ( MojoDescriptor mojo : mojos )
115 {
116 MojoDescriptor clone = mojo.clone();
117 clone.setPluginDescriptor( pluginDescriptor );
118 clones.add( clone );
119 }
120 }
121
122 return clones;
123 }
124
125 private static final class CacheKey
126 implements Key
127 {
128
129 private final String groupId;
130
131 private final String artifactId;
132
133 private final String version;
134
135 private final WorkspaceRepository workspace;
136
137 private final LocalRepository localRepo;
138
139 private final List<RemoteRepository> repositories;
140
141 private final int hashCode;
142
143 public CacheKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
144 {
145 groupId = plugin.getGroupId();
146 artifactId = plugin.getArtifactId();
147 version = plugin.getVersion();
148
149 workspace = CacheUtils.getWorkspace( session );
150 localRepo = session.getLocalRepository();
151 this.repositories = new ArrayList<RemoteRepository>( repositories.size() );
152 for ( RemoteRepository repository : repositories )
153 {
154 if ( repository.isRepositoryManager() )
155 {
156 this.repositories.addAll( repository.getMirroredRepositories() );
157 }
158 else
159 {
160 this.repositories.add( repository );
161 }
162 }
163
164 int hash = 17;
165 hash = hash * 31 + groupId.hashCode();
166 hash = hash * 31 + artifactId.hashCode();
167 hash = hash * 31 + version.hashCode();
168 hash = hash * 31 + hash( workspace );
169 hash = hash * 31 + localRepo.hashCode();
170 hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
171 this.hashCode = hash;
172 }
173
174 @Override
175 public int hashCode()
176 {
177 return hashCode;
178 }
179
180 @Override
181 public boolean equals( Object obj )
182 {
183 if ( this == obj )
184 {
185 return true;
186 }
187
188 if ( !( obj instanceof CacheKey ) )
189 {
190 return false;
191 }
192
193 CacheKey that = (CacheKey) obj;
194
195 return eq( this.artifactId, that.artifactId ) && eq( this.groupId, that.groupId )
196 && eq( this.version, that.version ) && eq( this.localRepo, that.localRepo )
197 && eq( this.workspace, that.workspace )
198 && CacheUtils.repositoriesEquals( this.repositories, that.repositories );
199 }
200
201 @Override
202 public String toString()
203 {
204 return groupId + ':' + artifactId + ':' + version;
205 }
206
207 private static int hash( Object obj )
208 {
209 return obj != null ? obj.hashCode() : 0;
210 }
211
212 private static <T> boolean eq( T s1, T s2 )
213 {
214 return s1 != null ? s1.equals( s2 ) : s2 == null;
215 }
216
217 }
218
219 }