View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl.synccontext.named;
20  
21  import java.util.Collection;
22  import java.util.TreeSet;
23  
24  import org.eclipse.aether.RepositorySystemSession;
25  import org.eclipse.aether.artifact.Artifact;
26  import org.eclipse.aether.metadata.Metadata;
27  import org.eclipse.aether.util.PathUtils;
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 suffixes and separators,
34   * hence this instance may or may not be filesystem friendly (depends on strings used).
35   * <p>
36   * Note: in earlier Resolver 1.9.x versions this mapper was the default, but it changed to {@link GAECVNameMapper}
37   * in 1.9.25.
38   */
39  public class GAVNameMapper implements NameMapper {
40      protected final boolean fileSystemFriendly;
41  
42      protected final String artifactPrefix;
43  
44      protected final String artifactSuffix;
45  
46      protected final String metadataPrefix;
47  
48      protected final String metadataSuffix;
49  
50      protected final String fieldSeparator;
51  
52      public GAVNameMapper(
53              boolean fileSystemFriendly,
54              String artifactPrefix,
55              String artifactSuffix,
56              String metadataPrefix,
57              String metadataSuffix,
58              String fieldSeparator) {
59          this.fileSystemFriendly = fileSystemFriendly;
60          this.artifactPrefix = requireNonNull(artifactPrefix);
61          this.artifactSuffix = requireNonNull(artifactSuffix);
62          this.metadataPrefix = requireNonNull(metadataPrefix);
63          this.metadataSuffix = requireNonNull(metadataSuffix);
64          this.fieldSeparator = requireNonNull(fieldSeparator);
65      }
66  
67      @Override
68      public boolean isFileSystemFriendly() {
69          return fileSystemFriendly;
70      }
71  
72      @Override
73      public Collection<String> nameLocks(
74              final RepositorySystemSession session,
75              final Collection<? extends Artifact> artifacts,
76              final Collection<? extends Metadata> metadatas) {
77          // Deadlock prevention: https://stackoverflow.com/a/16780988/696632
78          // We must acquire multiple locks always in the same order!
79          TreeSet<String> keys = new TreeSet<>();
80          if (artifacts != null) {
81              for (Artifact artifact : artifacts) {
82                  keys.add(getArtifactName(artifact));
83              }
84          }
85  
86          if (metadatas != null) {
87              for (Metadata metadata : metadatas) {
88                  keys.add(getMetadataName(metadata));
89              }
90          }
91          return keys;
92      }
93  
94      protected String getArtifactName(Artifact artifact) {
95          return artifactPrefix
96                  + artifact.getGroupId()
97                  + fieldSeparator
98                  + artifact.getArtifactId()
99                  + fieldSeparator
100                 + artifact.getBaseVersion()
101                 + artifactSuffix;
102     }
103 
104     protected static final String MAVEN_METADATA = "maven-metadata.xml";
105 
106     protected String getMetadataName(Metadata metadata) {
107         String name = metadataPrefix;
108         if (!metadata.getGroupId().isEmpty()) {
109             name += metadata.getGroupId();
110             if (!metadata.getArtifactId().isEmpty()) {
111                 name += fieldSeparator + metadata.getArtifactId();
112                 if (!metadata.getVersion().isEmpty()) {
113                     name += fieldSeparator + metadata.getVersion();
114                 }
115             }
116             if (!MAVEN_METADATA.equals(metadata.getType())) {
117                 name += fieldSeparator
118                         + (fileSystemFriendly ? PathUtils.stringToPathSegment(metadata.getType()) : metadata.getType());
119             }
120         } else {
121             if (!MAVEN_METADATA.equals(metadata.getType())) {
122                 name += (fileSystemFriendly ? PathUtils.stringToPathSegment(metadata.getType()) : metadata.getType());
123             }
124         }
125         return name + metadataSuffix;
126     }
127 
128     /**
129      * @deprecated Use {@link NameMappers} to create name mappers instead.
130      */
131     @Deprecated
132     public static NameMapper gav() {
133         return new GAVNameMapper(false, "artifact:", "", "metadata:", "", ":");
134     }
135 
136     /**
137      * @deprecated Use {@link NameMappers} to create name mappers instead.
138      */
139     @Deprecated
140     public static NameMapper fileGav() {
141         return new GAVNameMapper(true, "artifact~", ".lock", "metadata~", ".lock", "~");
142     }
143 }