1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl;
20
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Properties;
30 import java.util.function.Function;
31
32 import org.eclipse.aether.RepositorySystemSession;
33 import org.eclipse.aether.artifact.Artifact;
34 import org.eclipse.aether.metadata.Metadata;
35 import org.eclipse.aether.repository.ArtifactRepository;
36 import org.eclipse.aether.repository.LocalArtifactRegistration;
37 import org.eclipse.aether.repository.LocalArtifactRequest;
38 import org.eclipse.aether.repository.LocalArtifactResult;
39 import org.eclipse.aether.repository.RemoteRepository;
40
41 import static java.util.Objects.requireNonNull;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 class EnhancedLocalRepositoryManager extends SimpleLocalRepositoryManager {
63
64 private static final String LOCAL_REPO_ID = "";
65
66 private final String trackingFilename;
67
68 private final TrackingFileManager trackingFileManager;
69
70 private final LocalPathPrefixComposer localPathPrefixComposer;
71
72 EnhancedLocalRepositoryManager(
73 Path basedir,
74 LocalPathComposer localPathComposer,
75 Function<ArtifactRepository, String> idToPathSegmentFunction,
76 String trackingFilename,
77 TrackingFileManager trackingFileManager,
78 LocalPathPrefixComposer localPathPrefixComposer) {
79 super(basedir, "enhanced", localPathComposer, idToPathSegmentFunction);
80 this.trackingFilename = requireNonNull(trackingFilename);
81 this.trackingFileManager = requireNonNull(trackingFileManager);
82 this.localPathPrefixComposer = requireNonNull(localPathPrefixComposer);
83 }
84
85 private String concatPaths(String prefix, String artifactPath) {
86 if (prefix == null || prefix.isEmpty()) {
87 return artifactPath;
88 }
89 return prefix + '/' + artifactPath;
90 }
91
92 @Override
93 public String getPathForLocalArtifact(Artifact artifact) {
94 return concatPaths(
95 localPathPrefixComposer.getPathPrefixForLocalArtifact(artifact),
96 super.getPathForLocalArtifact(artifact));
97 }
98
99 @Override
100 public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
101 return concatPaths(
102 localPathPrefixComposer.getPathPrefixForRemoteArtifact(artifact, repository),
103 super.getPathForRemoteArtifact(artifact, repository, context));
104 }
105
106 @Override
107 public String getPathForLocalMetadata(Metadata metadata) {
108 return concatPaths(
109 localPathPrefixComposer.getPathPrefixForLocalMetadata(metadata),
110 super.getPathForLocalMetadata(metadata));
111 }
112
113 @Override
114 public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
115 return concatPaths(
116 localPathPrefixComposer.getPathPrefixForRemoteMetadata(metadata, repository),
117 super.getPathForRemoteMetadata(metadata, repository, context));
118 }
119
120 @Override
121 public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
122 Artifact artifact = request.getArtifact();
123 LocalArtifactResult result = new LocalArtifactResult(request);
124
125 Path filePath;
126
127
128 if (Objects.equals(artifact.getVersion(), artifact.getBaseVersion())) {
129 filePath = getAbsolutePathForLocalArtifact(artifact);
130 checkFind(filePath, result);
131 }
132
133 if (!result.isAvailable()) {
134 for (RemoteRepository repository : request.getRepositories()) {
135 filePath = getAbsolutePathForRemoteArtifact(artifact, repository, request.getContext());
136
137 checkFind(filePath, result);
138
139 if (result.isAvailable()) {
140 break;
141 }
142 }
143 }
144
145 return result;
146 }
147
148 private void checkFind(Path path, LocalArtifactResult result) {
149 if (Files.isRegularFile(path)) {
150 result.setPath(path);
151
152 Properties props = readRepos(path);
153
154 if (props.get(getKey(path, LOCAL_REPO_ID)) != null) {
155
156 result.setAvailable(true);
157 } else {
158 String context = result.getRequest().getContext();
159 for (RemoteRepository repository : result.getRequest().getRepositories()) {
160 if (props.get(getKey(path, getRepositoryKey(repository, context))) != null) {
161
162
163 result.setAvailable(true);
164 result.setRepository(repository);
165 break;
166 }
167 }
168 if (!result.isAvailable() && !isTracked(props, path)) {
169
170
171
172
173 result.setAvailable(true);
174 }
175 }
176 }
177 }
178
179 @Override
180 public void add(RepositorySystemSession session, LocalArtifactRegistration request) {
181 Collection<String> repositories;
182 if (request.getRepository() == null) {
183 repositories = Collections.singleton(LOCAL_REPO_ID);
184 } else {
185 repositories = getRepositoryKeys(request.getRepository(), request.getContexts());
186 }
187 if (request.getRepository() == null) {
188 addArtifact(request.getArtifact(), repositories, null, null);
189 } else {
190 for (String context : request.getContexts()) {
191 addArtifact(request.getArtifact(), repositories, request.getRepository(), context);
192 }
193 }
194 }
195
196 private Collection<String> getRepositoryKeys(RemoteRepository repository, Collection<String> contexts) {
197 Collection<String> keys = new HashSet<>();
198
199 if (contexts != null) {
200 for (String context : contexts) {
201 keys.add(getRepositoryKey(repository, context));
202 }
203 }
204
205 return keys;
206 }
207
208 private void addArtifact(
209 Artifact artifact, Collection<String> repositories, RemoteRepository repository, String context) {
210 requireNonNull(artifact, "artifact cannot be null");
211 Path file = repository == null
212 ? getAbsolutePathForLocalArtifact(artifact)
213 : getAbsolutePathForRemoteArtifact(artifact, repository, context);
214 addRepo(file, repositories);
215 }
216
217 private Properties readRepos(Path artifactPath) {
218 Path trackingFile = getTrackingFile(artifactPath);
219
220 Properties props = trackingFileManager.read(trackingFile);
221
222 return (props != null) ? props : new Properties();
223 }
224
225 private void addRepo(Path artifactPath, Collection<String> repositories) {
226 Map<String, String> updates = new HashMap<>();
227 for (String repository : repositories) {
228 updates.put(getKey(artifactPath, repository), "");
229 }
230
231 Path trackingPath = getTrackingFile(artifactPath);
232
233 trackingFileManager.update(trackingPath, updates);
234 }
235
236 private Path getTrackingFile(Path artifactPath) {
237 return artifactPath.getParent().resolve(trackingFilename);
238 }
239
240 private String getKey(Path path, String repository) {
241 return path.getFileName() + ">" + repository;
242 }
243
244 private boolean isTracked(Properties props, Path path) {
245 if (props != null) {
246 String keyPrefix = path.getFileName() + ">";
247 for (Object key : props.keySet()) {
248 if (key.toString().startsWith(keyPrefix)) {
249 return true;
250 }
251 }
252 }
253 return false;
254 }
255 }