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