1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.util.repository;
20
21 import java.nio.file.Files;
22 import java.nio.file.Path;
23 import java.util.List;
24
25 import org.eclipse.aether.ConfigurationProperties;
26 import org.eclipse.aether.RepositorySystemSession;
27 import org.eclipse.aether.artifact.Artifact;
28 import org.eclipse.aether.metadata.Metadata;
29 import org.eclipse.aether.repository.LocalArtifactRegistration;
30 import org.eclipse.aether.repository.LocalArtifactRequest;
31 import org.eclipse.aether.repository.LocalArtifactResult;
32 import org.eclipse.aether.repository.LocalMetadataRegistration;
33 import org.eclipse.aether.repository.LocalMetadataRequest;
34 import org.eclipse.aether.repository.LocalMetadataResult;
35 import org.eclipse.aether.repository.LocalRepository;
36 import org.eclipse.aether.repository.LocalRepositoryManager;
37 import org.eclipse.aether.repository.RemoteRepository;
38 import org.eclipse.aether.util.ConfigUtils;
39
40 import static java.util.Objects.requireNonNull;
41 import static java.util.stream.Collectors.toList;
42
43
44
45
46
47
48
49
50
51
52
53 public final class ChainedLocalRepositoryManager implements LocalRepositoryManager {
54 private static final String CONFIG_PROPS_PREFIX = ConfigurationProperties.PREFIX_AETHER + "chainedLocalRepository.";
55
56
57
58
59
60
61
62
63 public static final String CONFIG_PROP_IGNORE_TAIL_AVAILABILITY = CONFIG_PROPS_PREFIX + "ignoreTailAvailability";
64
65 public static final boolean DEFAULT_IGNORE_TAIL_AVAILABILITY = true;
66
67 private final LocalRepositoryManager head;
68
69 private final List<LocalRepositoryManager> tail;
70
71 private final boolean ignoreTailAvailability;
72
73 private final int installTarget;
74
75 private final int cacheTarget;
76
77 public ChainedLocalRepositoryManager(
78 LocalRepositoryManager head, List<LocalRepositoryManager> tail, boolean ignoreTailAvailability) {
79 this(head, tail, ignoreTailAvailability, 0, 0);
80 }
81
82 public ChainedLocalRepositoryManager(
83 LocalRepositoryManager head, List<LocalRepositoryManager> tail, RepositorySystemSession session) {
84 this(
85 head,
86 tail,
87 ConfigUtils.getBoolean(session, DEFAULT_IGNORE_TAIL_AVAILABILITY, CONFIG_PROP_IGNORE_TAIL_AVAILABILITY),
88 0,
89 0);
90 }
91
92
93
94
95
96
97
98
99
100
101
102 public ChainedLocalRepositoryManager(
103 LocalRepositoryManager head,
104 List<LocalRepositoryManager> tail,
105 boolean ignoreTailAvailability,
106 int installTarget,
107 int cacheTarget) {
108 this.head = requireNonNull(head, "head cannot be null");
109 this.tail = requireNonNull(tail, "tail cannot be null");
110 this.ignoreTailAvailability = ignoreTailAvailability;
111 if (installTarget < 0 || installTarget > tail.size()) {
112 throw new IllegalArgumentException("Illegal installTarget value");
113 }
114 this.installTarget = installTarget;
115 if (cacheTarget < 0 || cacheTarget > tail.size()) {
116 throw new IllegalArgumentException("Illegal cacheTarget value");
117 }
118 this.cacheTarget = cacheTarget;
119 }
120
121 @Override
122 public LocalRepository getRepository() {
123 return head.getRepository();
124 }
125
126 private LocalRepositoryManager getInstallTarget() {
127 if (installTarget == 0) {
128 return head;
129 } else {
130 return tail.get(installTarget - 1);
131 }
132 }
133
134 private LocalRepositoryManager getCacheTarget() {
135 if (cacheTarget == 0) {
136 return head;
137 } else {
138 return tail.get(cacheTarget - 1);
139 }
140 }
141
142 @Override
143 public Path getAbsolutePathForLocalArtifact(Artifact artifact) {
144 return getInstallTarget().getAbsolutePathForLocalArtifact(artifact);
145 }
146
147 @Override
148 public Path getAbsolutePathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
149 return getCacheTarget().getAbsolutePathForRemoteArtifact(artifact, repository, context);
150 }
151
152 @Override
153 public Path getAbsolutePathForLocalMetadata(Metadata metadata) {
154 return getInstallTarget().getAbsolutePathForLocalMetadata(metadata);
155 }
156
157 @Override
158 public Path getAbsolutePathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
159 return getCacheTarget().getAbsolutePathForRemoteMetadata(metadata, repository, context);
160 }
161
162 @Override
163 public String getPathForLocalArtifact(Artifact artifact) {
164 return getInstallTarget().getPathForLocalArtifact(artifact);
165 }
166
167 @Override
168 public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
169 return getCacheTarget().getPathForRemoteArtifact(artifact, repository, context);
170 }
171
172 @Override
173 public String getPathForLocalMetadata(Metadata metadata) {
174 return getInstallTarget().getPathForLocalMetadata(metadata);
175 }
176
177 @Override
178 public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
179 return getCacheTarget().getPathForRemoteMetadata(metadata, repository, context);
180 }
181
182 @Override
183 public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
184 LocalArtifactResult result = head.find(session, request);
185 if (result.isAvailable()) {
186 return result;
187 }
188
189 for (LocalRepositoryManager lrm : tail) {
190 result = lrm.find(session, request);
191 if (result.getPath() != null) {
192 if (ignoreTailAvailability) {
193 result.setAvailable(true);
194 return result;
195 } else if (result.isAvailable()) {
196 return result;
197 }
198 }
199 }
200 return new LocalArtifactResult(request);
201 }
202
203 @Override
204 public void add(RepositorySystemSession session, LocalArtifactRegistration request) {
205 String artifactPath;
206 LocalRepositoryManager target;
207 if (request.getRepository() != null) {
208 artifactPath = getPathForRemoteArtifact(request.getArtifact(), request.getRepository(), "check");
209 target = getCacheTarget();
210 } else {
211 artifactPath = getPathForLocalArtifact(request.getArtifact());
212 target = getInstallTarget();
213 }
214 Path file = target.getRepository().getBasePath().resolve(artifactPath);
215 if (Files.isRegularFile(file)) {
216 target.add(session, request);
217 }
218 }
219
220 @Override
221 public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) {
222 LocalMetadataResult result = head.find(session, request);
223 if (result.getPath() != null) {
224 return result;
225 }
226
227 for (LocalRepositoryManager lrm : tail) {
228 result = lrm.find(session, request);
229 if (result.getPath() != null) {
230 return result;
231 }
232 }
233 return new LocalMetadataResult(request);
234 }
235
236 @Override
237 public void add(RepositorySystemSession session, LocalMetadataRegistration request) {
238 String metadataPath;
239 LocalRepositoryManager target;
240 if (request.getRepository() != null) {
241 metadataPath = getPathForRemoteMetadata(request.getMetadata(), request.getRepository(), "check");
242 target = getCacheTarget();
243 } else {
244 metadataPath = getPathForLocalMetadata(request.getMetadata());
245 target = getInstallTarget();
246 }
247
248 Path file = target.getRepository().getBasePath().resolve(metadataPath);
249 if (Files.isRegularFile(file)) {
250 target.add(session, request);
251 }
252 }
253
254 @Override
255 public String toString() {
256 return head.getRepository().toString()
257 + tail.stream().map(LocalRepositoryManager::getRepository).collect(toList());
258 }
259 }