1 package org.apache.maven.artifact.repository.metadata; 2 3 18 19 import org.apache.maven.artifact.manager.WagonManager; 20 import org.apache.maven.artifact.metadata.ArtifactMetadata; 21 import org.apache.maven.artifact.repository.ArtifactRepository; 22 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; 23 import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; 24 import org.apache.maven.wagon.ResourceDoesNotExistException; 25 import org.apache.maven.wagon.TransferFailedException; 26 import org.codehaus.plexus.logging.AbstractLogEnabled; 27 import org.codehaus.plexus.util.IOUtil; 28 import org.codehaus.plexus.util.xml.pull.XmlPullParserException; 29 30 import java.io.File ; 31 import java.io.FileNotFoundException ; 32 import java.io.FileReader ; 33 import java.io.IOException ; 34 import java.io.Reader ; 35 import java.util.Date ; 36 import java.util.HashMap ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.Map ; 41 import java.util.Set ; 42 43 public class DefaultRepositoryMetadataManager 44 extends AbstractLogEnabled 45 implements RepositoryMetadataManager 46 { 47 private WagonManager wagonManager; 49 50 53 private Set cachedMetadata = new HashSet (); 54 55 public void resolve( RepositoryMetadata metadata, List remoteRepositories, ArtifactRepository localRepository ) 56 throws RepositoryMetadataResolutionException 57 { 58 boolean alreadyResolved = alreadyResolved( metadata ); 59 if ( !alreadyResolved ) 60 { 61 for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); ) 62 { 63 ArtifactRepository repository = (ArtifactRepository) i.next(); 64 65 ArtifactRepositoryPolicy policy = 66 metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases(); 67 68 if ( !policy.isEnabled() ) 69 { 70 getLogger().debug( "Skipping disabled repository " + repository.getId() ); 71 } 72 else if ( repository.isBlacklisted() ) 73 { 74 getLogger().debug( "Skipping blacklisted repository " + repository.getId() ); 75 } 76 else 77 { 78 File file = new File ( localRepository.getBasedir(), 79 localRepository.pathOfLocalRepositoryMetadata( metadata, repository ) ); 80 81 boolean checkForUpdates = policy.checkOutOfDate( new Date ( file.lastModified() ) ) || !file.exists(); 82 83 boolean metadataIsEmpty = true; 84 85 if ( checkForUpdates ) 86 { 87 getLogger().info( metadata.getKey() + ": checking for updates from " + repository.getId() ); 88 89 try 90 { 91 resolveAlways( metadata, repository, file, policy.getChecksumPolicy(), true ); 92 metadataIsEmpty = false; 93 } 94 catch ( TransferFailedException e ) 95 { 96 metadataIsEmpty = true; 99 } 100 } 101 102 if ( file.exists() ) 104 { 105 file.setLastModified( System.currentTimeMillis() ); 106 } 107 else if ( !metadataIsEmpty ) 108 { 109 try 111 { 112 metadata.storeInLocalRepository( localRepository, repository ); 113 } 114 catch ( RepositoryMetadataStoreException e ) 115 { 116 throw new RepositoryMetadataResolutionException( 117 "Unable to store local copy of metadata: " + e.getMessage(), e ); 118 } 119 } 120 } 121 } 122 cachedMetadata.add( metadata.getKey() ); 123 } 124 125 try 126 { 127 mergeMetadata( metadata, remoteRepositories, localRepository ); 128 } 129 catch ( RepositoryMetadataStoreException e ) 130 { 131 throw new RepositoryMetadataResolutionException( 132 "Unable to store local copy of metadata: " + e.getMessage(), e ); 133 } 134 catch ( RepositoryMetadataReadException e ) 135 { 136 throw new RepositoryMetadataResolutionException( "Unable to read local copy of metadata: " + e.getMessage(), 137 e ); 138 } 139 } 140 141 private void mergeMetadata( RepositoryMetadata metadata, List remoteRepositories, 142 ArtifactRepository localRepository ) 143 throws RepositoryMetadataStoreException, RepositoryMetadataReadException 144 { 145 150 Map previousMetadata = new HashMap (); 151 ArtifactRepository selected = null; 152 for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); ) 153 { 154 ArtifactRepository repository = (ArtifactRepository) i.next(); 155 156 ArtifactRepositoryPolicy policy = 157 metadata.isSnapshot() ? repository.getSnapshots() : repository.getReleases(); 158 159 if ( policy.isEnabled() && !repository.isBlacklisted() ) 160 { 161 if ( loadMetadata( metadata, repository, localRepository, previousMetadata ) ) 162 { 163 metadata.setRepository( repository ); 164 selected = repository; 165 } 166 } 167 } 168 if ( loadMetadata( metadata, localRepository, localRepository, previousMetadata ) ) 169 { 170 metadata.setRepository( null ); 171 selected = localRepository; 172 } 173 174 updateSnapshotMetadata( metadata, previousMetadata, selected, localRepository ); 175 } 176 177 private void updateSnapshotMetadata( RepositoryMetadata metadata, Map previousMetadata, ArtifactRepository selected, 178 ArtifactRepository localRepository ) 179 throws RepositoryMetadataStoreException 180 { 181 if ( metadata.isSnapshot() ) 183 { 184 Metadata prevMetadata = metadata.getMetadata(); 185 186 for ( Iterator i = previousMetadata.keySet().iterator(); i.hasNext(); ) 187 { 188 ArtifactRepository repository = (ArtifactRepository) i.next(); 189 Metadata m = (Metadata) previousMetadata.get( repository ); 190 if ( repository.equals( selected ) ) 191 { 192 if ( m.getVersioning() == null ) 193 { 194 m.setVersioning( new Versioning() ); 195 } 196 197 if ( m.getVersioning().getSnapshot() == null ) 198 { 199 m.getVersioning().setSnapshot( new Snapshot() ); 200 } 201 202 if ( !m.getVersioning().getSnapshot().isLocalCopy() ) 203 { 204 m.getVersioning().getSnapshot().setLocalCopy( true ); 205 metadata.setMetadata( m ); 206 metadata.storeInLocalRepository( localRepository, repository ); 207 } 208 } 209 else 210 { 211 if ( m.getVersioning() != null && m.getVersioning().getSnapshot() != null && 212 m.getVersioning().getSnapshot().isLocalCopy() ) 213 { 214 m.getVersioning().getSnapshot().setLocalCopy( false ); 215 metadata.setMetadata( m ); 216 metadata.storeInLocalRepository( localRepository, repository ); 217 } 218 } 219 } 220 221 metadata.setMetadata( prevMetadata ); 222 } 223 } 224 225 private boolean loadMetadata( RepositoryMetadata repoMetadata, ArtifactRepository remoteRepository, 226 ArtifactRepository localRepository, Map previousMetadata ) 227 throws RepositoryMetadataReadException 228 { 229 boolean setRepository = false; 230 231 File metadataFile = new File ( localRepository.getBasedir(), 232 localRepository.pathOfLocalRepositoryMetadata( repoMetadata, remoteRepository ) ); 233 234 if ( metadataFile.exists() ) 235 { 236 Metadata metadata = readMetadata( metadataFile ); 237 238 if ( repoMetadata.isSnapshot() && previousMetadata != null ) 239 { 240 previousMetadata.put( remoteRepository, metadata ); 241 } 242 243 if ( repoMetadata.getMetadata() != null ) 244 { 245 setRepository = repoMetadata.getMetadata().merge( metadata ); 246 } 247 else 248 { 249 repoMetadata.setMetadata( metadata ); 250 setRepository = true; 251 } 252 } 253 return setRepository; 254 } 255 256 259 protected static Metadata readMetadata( File mappingFile ) 260 throws RepositoryMetadataReadException 261 { 262 Metadata result; 263 264 Reader fileReader = null; 265 try 266 { 267 fileReader = new FileReader ( mappingFile ); 268 269 MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); 270 271 result = mappingReader.read( fileReader, false ); 272 } 273 catch ( FileNotFoundException e ) 274 { 275 throw new RepositoryMetadataReadException( "Cannot read metadata from '" + mappingFile + "'", e ); 276 } 277 catch ( IOException e ) 278 { 279 throw new RepositoryMetadataReadException( 280 "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); 281 } 282 catch ( XmlPullParserException e ) 283 { 284 throw new RepositoryMetadataReadException( 285 "Cannot read metadata from '" + mappingFile + "': " + e.getMessage(), e ); 286 } 287 finally 288 { 289 IOUtil.close( fileReader ); 290 } 291 return result; 292 } 293 294 public void resolveAlways( RepositoryMetadata metadata, ArtifactRepository localRepository, 295 ArtifactRepository remoteRepository ) 296 throws RepositoryMetadataResolutionException 297 { 298 if ( !wagonManager.isOnline() ) 299 { 300 throw new RepositoryMetadataResolutionException( 302 "System is offline. Cannot resolve required metadata:\n" + metadata.extendedToString() ); 303 } 304 305 File file = new File ( localRepository.getBasedir(), 306 localRepository.pathOfLocalRepositoryMetadata( metadata, remoteRepository ) ); 307 308 try 309 { 310 resolveAlways( metadata, remoteRepository, file, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN, false ); 311 } 312 catch ( TransferFailedException e ) 313 { 314 } 319 320 try 321 { 322 if ( file.exists() ) 323 { 324 Metadata prevMetadata = readMetadata( file ); 325 metadata.setMetadata( prevMetadata ); 326 } 327 } 328 catch ( RepositoryMetadataReadException e ) 329 { 330 throw new RepositoryMetadataResolutionException( e.getMessage(), e ); 331 } 332 } 333 334 private void resolveAlways( ArtifactMetadata metadata, ArtifactRepository repository, File file, 335 String checksumPolicy, boolean allowBlacklisting ) 336 throws RepositoryMetadataResolutionException, TransferFailedException 337 { 338 if ( !wagonManager.isOnline() ) 339 { 340 if ( allowBlacklisting ) 341 { 342 getLogger().debug( 343 "System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n" ); 344 return; 345 } 346 else 347 { 348 throw new RepositoryMetadataResolutionException( 350 "System is offline. Cannot resolve required metadata:\n" + metadata.extendedToString() ); 351 } 352 } 353 354 try 355 { 356 wagonManager.getArtifactMetadata( metadata, repository, file, checksumPolicy ); 357 } 358 catch ( ResourceDoesNotExistException e ) 359 { 360 getLogger().debug( metadata + " could not be found on repository: " + repository.getId() ); 361 362 if ( file.exists() ) 364 { 365 file.delete(); 366 } 367 } 368 catch ( TransferFailedException e ) 369 { 370 getLogger().warn( metadata + " could not be retrieved from repository: " + repository.getId() + 371 " due to an error: " + e.getMessage() ); 372 getLogger().info( "Repository '" + repository.getId() + "' will be blacklisted" ); 373 getLogger().debug( "Exception", e ); 374 repository.setBlacklisted( allowBlacklisting ); 375 376 throw e; 377 } 378 } 379 380 private boolean alreadyResolved( ArtifactMetadata metadata ) 381 { 382 return cachedMetadata.contains( metadata.getKey() ); 383 } 384 385 public void deploy( ArtifactMetadata metadata, ArtifactRepository localRepository, 386 ArtifactRepository deploymentRepository ) 387 throws RepositoryMetadataDeploymentException 388 { 389 if ( !wagonManager.isOnline() ) 390 { 391 throw new RepositoryMetadataDeploymentException( 393 "System is offline. Cannot deploy metadata:\n" + metadata.extendedToString() ); 394 } 395 396 getLogger().info( "Retrieving previous metadata from " + deploymentRepository.getId() ); 397 398 File file = new File ( localRepository.getBasedir(), 399 localRepository.pathOfLocalRepositoryMetadata( metadata, deploymentRepository ) ); 400 401 try 402 { 403 resolveAlways( metadata, deploymentRepository, file, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN, false ); 404 } 405 catch ( RepositoryMetadataResolutionException e ) 406 { 407 throw new RepositoryMetadataDeploymentException( 408 "Unable to get previous metadata to update: " + e.getMessage(), e ); 409 } 410 catch ( TransferFailedException e ) 411 { 412 } 417 418 try 419 { 420 metadata.storeInLocalRepository( localRepository, deploymentRepository ); 421 } 422 catch ( RepositoryMetadataStoreException e ) 423 { 424 throw new RepositoryMetadataDeploymentException( "Error installing metadata: " + e.getMessage(), e ); 425 } 426 427 try 428 { 429 wagonManager.putArtifactMetadata( file, metadata, deploymentRepository ); 430 } 431 catch ( TransferFailedException e ) 432 { 433 throw new RepositoryMetadataDeploymentException( "Error while deploying metadata: " + e.getMessage(), e ); 434 } 435 } 436 437 public void install( ArtifactMetadata metadata, ArtifactRepository localRepository ) 438 throws RepositoryMetadataInstallationException 439 { 440 try 441 { 442 metadata.storeInLocalRepository( localRepository, localRepository ); 443 } 444 catch ( RepositoryMetadataStoreException e ) 445 { 446 throw new RepositoryMetadataInstallationException( "Error installing metadata: " + e.getMessage(), e ); 447 } 448 } 449 } 450 | Popular Tags |