001package org.eclipse.aether.internal.impl.synccontext.named; 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 022import java.util.Collection; 023import java.util.TreeSet; 024 025import org.eclipse.aether.RepositorySystemSession; 026import org.eclipse.aether.artifact.Artifact; 027import org.eclipse.aether.metadata.Metadata; 028 029import static java.util.Objects.requireNonNull; 030 031/** 032 * Artifact GAV {@link NameMapper}, uses artifact and metadata coordinates to name their corresponding locks. Is not 033 * considering local repository, only the artifact coordinates. May use custom prefixes and sufixes and separators, 034 * hence this instance may or may not be filesystem friendly (depends on strings used). 035 */ 036public class GAVNameMapper implements NameMapper 037{ 038 private final boolean fileSystemFriendly; 039 040 private final String artifactPrefix; 041 042 private final String artifactSuffix; 043 044 private final String metadataPrefix; 045 046 private final String metadataSuffix; 047 048 private final String fieldSeparator; 049 050 public GAVNameMapper( boolean fileSystemFriendly, 051 String artifactPrefix, String artifactSuffix, 052 String metadataPrefix, String metadataSuffix, 053 String fieldSeparator ) 054 { 055 this.fileSystemFriendly = fileSystemFriendly; 056 this.artifactPrefix = requireNonNull( artifactPrefix ); 057 this.artifactSuffix = requireNonNull( artifactSuffix ); 058 this.metadataPrefix = requireNonNull( metadataPrefix ); 059 this.metadataSuffix = requireNonNull( metadataSuffix ); 060 this.fieldSeparator = requireNonNull( fieldSeparator ); 061 } 062 063 @Override 064 public boolean isFileSystemFriendly() 065 { 066 return fileSystemFriendly; 067 } 068 069 @Override 070 public Collection<String> nameLocks( final RepositorySystemSession session, 071 final Collection<? extends Artifact> artifacts, 072 final Collection<? extends Metadata> metadatas ) 073 { 074 // Deadlock prevention: https://stackoverflow.com/a/16780988/696632 075 // We must acquire multiple locks always in the same order! 076 TreeSet<String> keys = new TreeSet<>(); 077 if ( artifacts != null ) 078 { 079 for ( Artifact artifact : artifacts ) 080 { 081 keys.add( getArtifactName( artifact ) ); 082 } 083 } 084 085 if ( metadatas != null ) 086 { 087 for ( Metadata metadata : metadatas ) 088 { 089 keys.add( getMetadataName( metadata ) ); 090 } 091 } 092 return keys; 093 } 094 095 private String getArtifactName( Artifact artifact ) 096 { 097 return artifactPrefix + artifact.getGroupId() 098 + fieldSeparator + artifact.getArtifactId() 099 + fieldSeparator + artifact.getBaseVersion() 100 + artifactSuffix; 101 } 102 103 private String getMetadataName( Metadata metadata ) 104 { 105 String name = metadataPrefix; 106 if ( !metadata.getGroupId().isEmpty() ) 107 { 108 name += metadata.getGroupId(); 109 if ( !metadata.getArtifactId().isEmpty() ) 110 { 111 name += fieldSeparator + metadata.getArtifactId(); 112 if ( !metadata.getVersion().isEmpty() ) 113 { 114 name += fieldSeparator + metadata.getVersion(); 115 } 116 } 117 } 118 return name + metadataSuffix; 119 } 120 121 public static NameMapper gav() 122 { 123 return new GAVNameMapper( false, "artifact:", "", "metadata:", "", ":" ); 124 } 125 126 public static NameMapper fileGav() 127 { 128 return new GAVNameMapper( true, "", ".lock", "", ".lock", "~" ); 129 } 130}