1 package org.eclipse.aether.internal.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.eclipse.aether.RepositorySystemSession;
23 import org.eclipse.aether.spi.connector.ArtifactDownload;
24 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
25 import org.eclipse.aether.spi.connector.checksum.ProvidedChecksumsSource;
26 import org.eclipse.aether.spi.io.FileProcessor;
27 import org.eclipse.aether.util.ConfigUtils;
28 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import javax.inject.Inject;
33 import javax.inject.Named;
34 import javax.inject.Singleton;
35 import java.io.IOException;
36 import java.net.URI;
37 import java.nio.file.Files;
38 import java.nio.file.Path;
39 import java.nio.file.Paths;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44
45 import static java.util.Objects.requireNonNull;
46
47
48
49
50
51
52
53
54
55 @Singleton
56 @Named( FileProvidedChecksumsSource.NAME )
57 public final class FileProvidedChecksumsSource
58 implements ProvidedChecksumsSource
59 {
60 public static final String NAME = "file";
61
62 static final String CONFIG_PROP_BASE_DIR = "aether.artifactResolver.providedChecksumsSource.file.baseDir";
63
64 static final String LOCAL_REPO_PREFIX = ".checksums";
65
66 private static final Logger LOGGER = LoggerFactory.getLogger( FileProvidedChecksumsSource.class );
67
68 private final FileProcessor fileProcessor;
69
70 private final LocalPathComposer localPathComposer;
71
72 @Inject
73 public FileProvidedChecksumsSource( FileProcessor fileProcessor, LocalPathComposer localPathComposer )
74 {
75 this.fileProcessor = requireNonNull( fileProcessor );
76 this.localPathComposer = requireNonNull( localPathComposer );
77 }
78
79 @Override
80 public Map<String, String> getProvidedArtifactChecksums( RepositorySystemSession session,
81 ArtifactDownload transfer,
82 List<ChecksumAlgorithmFactory> checksumAlgorithmFactories )
83 {
84 Path baseDir = getBaseDir( session );
85 if ( baseDir == null )
86 {
87 return null;
88 }
89 ArrayList<ChecksumFilePath> checksumFilePaths = new ArrayList<>( checksumAlgorithmFactories.size() );
90 for ( ChecksumAlgorithmFactory checksumAlgorithmFactory : checksumAlgorithmFactories )
91 {
92 checksumFilePaths.add( new ChecksumFilePath(
93 localPathComposer.getPathForArtifact( transfer.getArtifact(), false ) + '.'
94 + checksumAlgorithmFactory.getFileExtension(), checksumAlgorithmFactory ) );
95 }
96 return getProvidedChecksums( baseDir, checksumFilePaths, ArtifactIdUtils.toId( transfer.getArtifact() ) );
97 }
98
99
100
101
102 private Map<String, String> getProvidedChecksums( Path baseDir,
103 List<ChecksumFilePath> checksumFilePaths,
104 String subjectId )
105 {
106 HashMap<String, String> checksums = new HashMap<>();
107 for ( ChecksumFilePath checksumFilePath : checksumFilePaths )
108 {
109 Path checksumPath = baseDir.resolve( checksumFilePath.path );
110 if ( Files.isReadable( checksumPath ) )
111 {
112 try
113 {
114 String checksum = fileProcessor.readChecksum( checksumPath.toFile() );
115 if ( checksum != null )
116 {
117 LOGGER.debug( "Resolved provided checksum '{}:{}' for '{}'",
118 checksumFilePath.checksumAlgorithmFactory.getName(), checksum, subjectId );
119
120 checksums.put( checksumFilePath.checksumAlgorithmFactory.getName(), checksum );
121 }
122 }
123 catch ( IOException e )
124 {
125 LOGGER.warn( "Could not read provided checksum for '{}' at path '{}'",
126 subjectId, checksumPath, e );
127 }
128 }
129 }
130 return checksums.isEmpty() ? null : checksums;
131 }
132
133
134
135
136 private Path getBaseDir( RepositorySystemSession session )
137 {
138 final String baseDirPath = ConfigUtils.getString( session, null, CONFIG_PROP_BASE_DIR );
139 final Path baseDir;
140 if ( baseDirPath != null )
141 {
142 baseDir = Paths.get( baseDirPath );
143 }
144 else
145 {
146 baseDir = session.getLocalRepository().getBasedir().toPath().resolve( LOCAL_REPO_PREFIX );
147 }
148 if ( !Files.isDirectory( baseDir ) )
149 {
150 return null;
151 }
152 return baseDir;
153 }
154
155 private static final class ChecksumFilePath
156 {
157 private final String path;
158
159 private final ChecksumAlgorithmFactory checksumAlgorithmFactory;
160
161 private ChecksumFilePath( String path, ChecksumAlgorithmFactory checksumAlgorithmFactory )
162 {
163 this.path = path;
164 this.checksumAlgorithmFactory = checksumAlgorithmFactory;
165 }
166 }
167 }