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