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 }