1 package org.eclipse.aether.internal.impl.synccontext.named;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collection;
23 import java.util.stream.Collectors;
24
25 import org.eclipse.aether.RepositorySystemSession;
26 import org.eclipse.aether.artifact.Artifact;
27 import org.eclipse.aether.metadata.Metadata;
28 import org.eclipse.aether.util.ConfigUtils;
29 import org.eclipse.aether.util.StringDigestUtil;
30
31 import static java.util.Objects.requireNonNull;
32
33
34
35
36
37
38
39
40
41
42
43 public class HashingNameMapper implements NameMapper
44 {
45 private static final String CONFIG_PROP_DEPTH = "aether.syncContext.named.hashing.depth";
46
47 private final NameMapper delegate;
48
49 public HashingNameMapper( final NameMapper delegate )
50 {
51 this.delegate = requireNonNull( delegate );
52 }
53
54 @Override
55 public boolean isFileSystemFriendly()
56 {
57 return true;
58 }
59
60 @Override
61 public Collection<String> nameLocks( RepositorySystemSession session,
62 Collection<? extends Artifact> artifacts,
63 Collection<? extends Metadata> metadatas )
64 {
65 final int depth = ConfigUtils.getInteger( session, 2, CONFIG_PROP_DEPTH );
66 if ( depth < 0 || depth > 4 )
67 {
68 throw new IllegalArgumentException( "allowed depth value is between 0 and 4 (inclusive)" );
69 }
70 return delegate.nameLocks( session, artifacts, metadatas ).stream()
71 .map( n -> hashName( n, depth ) )
72 .collect( Collectors.toList() );
73 }
74
75 private String hashName( final String name, final int depth )
76 {
77 String hashedName = StringDigestUtil.sha1( name );
78 if ( depth == 0 )
79 {
80 return hashedName;
81 }
82 StringBuilder prefix = new StringBuilder( "" );
83 int i = 0;
84 while ( i < hashedName.length() && i / 2 < depth )
85 {
86 prefix.append( hashedName, i, i + 2 ).append( "/" );
87 i += 2;
88 }
89 return prefix.append( hashedName ).toString();
90 }
91 }