View Javadoc
1   package org.eclipse.aether.internal.impl.synccontext.named;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Collection;
23  import java.util.TreeSet;
24  
25  import org.eclipse.aether.RepositorySystemSession;
26  import org.eclipse.aether.artifact.Artifact;
27  import org.eclipse.aether.metadata.Metadata;
28  
29  import static java.util.Objects.requireNonNull;
30  
31  /**
32   * Artifact GAV {@link NameMapper}, uses artifact and metadata coordinates to name their corresponding locks. Is not
33   * considering local repository, only the artifact coordinates. May use custom prefixes and sufixes and separators,
34   * hence this instance may or may not be filesystem friendly (depends on strings used).
35   */
36  public class GAVNameMapper implements NameMapper
37  {
38      private final boolean fileSystemFriendly;
39  
40      private final String artifactPrefix;
41  
42      private final String artifactSuffix;
43  
44      private final String metadataPrefix;
45  
46      private final String metadataSuffix;
47  
48      private final String fieldSeparator;
49  
50      public GAVNameMapper( boolean fileSystemFriendly,
51                            String artifactPrefix, String artifactSuffix,
52                            String metadataPrefix, String metadataSuffix,
53                            String fieldSeparator )
54      {
55          this.fileSystemFriendly = fileSystemFriendly;
56          this.artifactPrefix = requireNonNull( artifactPrefix );
57          this.artifactSuffix = requireNonNull( artifactSuffix );
58          this.metadataPrefix = requireNonNull( metadataPrefix );
59          this.metadataSuffix = requireNonNull( metadataSuffix );
60          this.fieldSeparator = requireNonNull( fieldSeparator );
61      }
62  
63      @Override
64      public boolean isFileSystemFriendly()
65      {
66          return fileSystemFriendly;
67      }
68  
69      @Override
70      public Collection<String> nameLocks( final RepositorySystemSession session,
71                                           final Collection<? extends Artifact> artifacts,
72                                           final Collection<? extends Metadata> metadatas )
73      {
74          // Deadlock prevention: https://stackoverflow.com/a/16780988/696632
75          // We must acquire multiple locks always in the same order!
76          TreeSet<String> keys = new TreeSet<>();
77          if ( artifacts != null )
78          {
79              for ( Artifact artifact : artifacts )
80              {
81                  keys.add( getArtifactName( artifact ) );
82              }
83          }
84  
85          if ( metadatas != null )
86          {
87              for ( Metadata metadata : metadatas )
88              {
89                  keys.add( getMetadataName( metadata ) );
90              }
91          }
92          return keys;
93      }
94  
95      private String getArtifactName( Artifact artifact )
96      {
97          return artifactPrefix + artifact.getGroupId()
98                  + fieldSeparator + artifact.getArtifactId()
99                  + 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 }