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.sonatype.aether.RepositorySystemSession;
034 import org.sonatype.aether.repository.LocalRepository;
035 import org.sonatype.aether.repository.RemoteRepository;
036 import org.sonatype.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
101 return clone;
102 }
103
104 private static List<ComponentDescriptor<?>> clone( List<MojoDescriptor> mojos, PluginDescriptor pluginDescriptor )
105 {
106 List<ComponentDescriptor<?>> clones = null;
107
108 if ( mojos != null )
109 {
110 clones = new ArrayList<ComponentDescriptor<?>>( mojos.size() );
111
112 for ( MojoDescriptor mojo : mojos )
113 {
114 MojoDescriptor clone = mojo.clone();
115 clone.setPluginDescriptor( pluginDescriptor );
116 clones.add( clone );
117 }
118 }
119
120 return clones;
121 }
122
123 private static final class CacheKey
124 implements Key
125 {
126
127 private final String groupId;
128
129 private final String artifactId;
130
131 private final String version;
132
133 private final WorkspaceRepository workspace;
134
135 private final LocalRepository localRepo;
136
137 private final List<RemoteRepository> repositories;
138
139 private final int hashCode;
140
141 public CacheKey( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
142 {
143 groupId = plugin.getGroupId();
144 artifactId = plugin.getArtifactId();
145 version = plugin.getVersion();
146
147 workspace = CacheUtils.getWorkspace( session );
148 localRepo = session.getLocalRepository();
149 this.repositories = new ArrayList<RemoteRepository>( repositories.size() );
150 for ( RemoteRepository repository : repositories )
151 {
152 if ( repository.isRepositoryManager() )
153 {
154 this.repositories.addAll( repository.getMirroredRepositories() );
155 }
156 else
157 {
158 this.repositories.add( repository );
159 }
160 }
161
162 int hash = 17;
163 hash = hash * 31 + groupId.hashCode();
164 hash = hash * 31 + artifactId.hashCode();
165 hash = hash * 31 + version.hashCode();
166 hash = hash * 31 + hash( workspace );
167 hash = hash * 31 + localRepo.hashCode();
168 hash = hash * 31 + CacheUtils.repositoriesHashCode( repositories );
169 this.hashCode = hash;
170 }
171
172 @Override
173 public int hashCode()
174 {
175 return hashCode;
176 }
177
178 @Override
179 public boolean equals( Object obj )
180 {
181 if ( this == obj )
182 {
183 return true;
184 }
185
186 if ( !( obj instanceof CacheKey ) )
187 {
188 return false;
189 }
190
191 CacheKey that = (CacheKey) obj;
192
193 return eq( this.artifactId, that.artifactId ) && eq( this.groupId, that.groupId )
194 && eq( this.version, that.version ) && eq( this.localRepo, that.localRepo )
195 && eq( this.workspace, that.workspace )
196 && CacheUtils.repositoriesEquals( this.repositories, that.repositories );
197 }
198
199 @Override
200 public String toString()
201 {
202 return groupId + ':' + artifactId + ':' + version;
203 }
204
205 private static int hash( Object obj )
206 {
207 return obj != null ? obj.hashCode() : 0;
208 }
209
210 private static <T> boolean eq( T s1, T s2 )
211 {
212 return s1 != null ? s1.equals( s2 ) : s2 == null;
213 }
214
215 }
216
217 }