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 javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.util.*;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.IdentityHashMap;
31 import java.util.List;
32 import java.util.ListIterator;
33 import java.util.Map;
34
35 import org.eclipse.aether.RepositoryEvent;
36 import org.eclipse.aether.RepositoryEvent.EventType;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.RequestTrace;
39 import org.eclipse.aether.SyncContext;
40 import org.eclipse.aether.artifact.Artifact;
41 import org.eclipse.aether.impl.Installer;
42 import org.eclipse.aether.impl.MetadataGenerator;
43 import org.eclipse.aether.impl.MetadataGeneratorFactory;
44 import org.eclipse.aether.impl.RepositoryEventDispatcher;
45 import org.eclipse.aether.installation.InstallRequest;
46 import org.eclipse.aether.installation.InstallResult;
47 import org.eclipse.aether.installation.InstallationException;
48 import org.eclipse.aether.metadata.MergeableMetadata;
49 import org.eclipse.aether.metadata.Metadata;
50 import org.eclipse.aether.repository.LocalArtifactRegistration;
51 import org.eclipse.aether.repository.LocalMetadataRegistration;
52 import org.eclipse.aether.repository.LocalRepositoryManager;
53 import org.eclipse.aether.spi.artifact.generator.ArtifactGenerator;
54 import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory;
55 import org.eclipse.aether.spi.io.PathProcessor;
56 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 import static java.util.Objects.requireNonNull;
61
62
63
64 @Singleton
65 @Named
66 public class DefaultInstaller implements Installer {
67 private final Logger logger = LoggerFactory.getLogger(getClass());
68
69 private final PathProcessor pathProcessor;
70
71 private final RepositoryEventDispatcher repositoryEventDispatcher;
72
73 private final Map<String, ArtifactGeneratorFactory> artifactFactories;
74
75 private final Map<String, MetadataGeneratorFactory> metadataFactories;
76
77 private final SyncContextFactory syncContextFactory;
78
79 @Inject
80 public DefaultInstaller(
81 PathProcessor pathProcessor,
82 RepositoryEventDispatcher repositoryEventDispatcher,
83 Map<String, ArtifactGeneratorFactory> artifactFactories,
84 Map<String, MetadataGeneratorFactory> metadataFactories,
85 SyncContextFactory syncContextFactory) {
86 this.pathProcessor = requireNonNull(pathProcessor, "path processor cannot be null");
87 this.repositoryEventDispatcher =
88 requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
89 this.artifactFactories = Collections.unmodifiableMap(artifactFactories);
90 this.metadataFactories = Collections.unmodifiableMap(metadataFactories);
91 this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
92 }
93
94 @Override
95 public InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException {
96 requireNonNull(session, "session cannot be null");
97 requireNonNull(request, "request cannot be null");
98 try (SyncContext syncContext = syncContextFactory.newInstance(session, false)) {
99 return install(syncContext, session, request);
100 }
101 }
102
103 private InstallResult install(SyncContext syncContext, RepositorySystemSession session, InstallRequest request)
104 throws InstallationException {
105 InstallResult result = new InstallResult(request);
106
107 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
108
109 List<Artifact> artifacts = new ArrayList<>(request.getArtifacts());
110 List<? extends ArtifactGenerator> artifactGenerators = getArtifactGenerators(session, request);
111 try {
112 List<Artifact> generatedArtifacts = new ArrayList<>();
113 for (ArtifactGenerator artifactGenerator : artifactGenerators) {
114 Collection<? extends Artifact> generated = artifactGenerator.generate(generatedArtifacts);
115 for (Artifact generatedArtifact : generated) {
116 Map<String, String> properties = new HashMap<>(generatedArtifact.getProperties());
117 properties.put(
118 ArtifactGeneratorFactory.ARTIFACT_GENERATOR_ID,
119 requireNonNull(artifactGenerator.generatorId(), "generatorId"));
120 Artifact ga = generatedArtifact.setProperties(properties);
121 generatedArtifacts.add(ga);
122 }
123 }
124 artifacts.addAll(generatedArtifacts);
125
126 List<? extends MetadataGenerator> metadataGenerators = getMetadataGenerators(session, request);
127
128 IdentityHashMap<Metadata, Object> processedMetadata = new IdentityHashMap<>();
129
130 List<Metadata> metadatas = Utils.prepareMetadata(metadataGenerators, artifacts);
131
132 syncContext.acquire(artifacts, Utils.combine(request.getMetadata(), metadatas));
133
134 for (Metadata metadata : metadatas) {
135 install(session, trace, metadata);
136 processedMetadata.put(metadata, null);
137 result.addMetadata(metadata);
138 }
139
140 for (ListIterator<Artifact> iterator = artifacts.listIterator(); iterator.hasNext(); ) {
141 Artifact artifact = iterator.next();
142
143 for (MetadataGenerator generator : metadataGenerators) {
144 artifact = generator.transformArtifact(artifact);
145 }
146
147 iterator.set(artifact);
148
149 install(session, trace, artifact);
150 if (artifact.getProperty(ArtifactGeneratorFactory.ARTIFACT_GENERATOR_ID, null) == null) {
151 result.addArtifact(artifact);
152 }
153 }
154
155 metadatas = Utils.finishMetadata(metadataGenerators, artifacts);
156
157 syncContext.acquire(null, metadatas);
158
159 for (Metadata metadata : metadatas) {
160 install(session, trace, metadata);
161 processedMetadata.put(metadata, null);
162 result.addMetadata(metadata);
163 }
164
165 for (Metadata metadata : request.getMetadata()) {
166 if (!processedMetadata.containsKey(metadata)) {
167 install(session, trace, metadata);
168 result.addMetadata(metadata);
169 }
170 }
171
172 return result;
173 } finally {
174 for (ArtifactGenerator artifactGenerator : artifactGenerators) {
175 try {
176 artifactGenerator.close();
177 } catch (Exception e) {
178 logger.warn("ArtifactGenerator close failure: {}", artifactGenerator.generatorId(), e);
179 }
180 }
181 }
182 }
183
184 private List<? extends ArtifactGenerator> getArtifactGenerators(
185 RepositorySystemSession session, InstallRequest request) {
186 PrioritizedComponents<ArtifactGeneratorFactory> factories =
187 Utils.sortArtifactGeneratorFactories(session, artifactFactories);
188
189 List<ArtifactGenerator> generators = new ArrayList<>();
190
191 for (PrioritizedComponent<ArtifactGeneratorFactory> factory : factories.getEnabled()) {
192 ArtifactGenerator generator = factory.getComponent().newInstance(session, request);
193 if (generator != null) {
194 generators.add(generator);
195 }
196 }
197
198 return generators;
199 }
200
201 private List<? extends MetadataGenerator> getMetadataGenerators(
202 RepositorySystemSession session, InstallRequest request) {
203 PrioritizedComponents<MetadataGeneratorFactory> factories =
204 Utils.sortMetadataGeneratorFactories(session, metadataFactories);
205
206 List<MetadataGenerator> generators = new ArrayList<>();
207
208 for (PrioritizedComponent<MetadataGeneratorFactory> factory : factories.getEnabled()) {
209 MetadataGenerator generator = factory.getComponent().newInstance(session, request);
210 if (generator != null) {
211 generators.add(generator);
212 }
213 }
214
215 return generators;
216 }
217
218 private void install(RepositorySystemSession session, RequestTrace trace, Artifact artifact)
219 throws InstallationException {
220 final LocalRepositoryManager lrm = session.getLocalRepositoryManager();
221 final Path srcPath = artifact.getPath();
222 final Path dstPath = lrm.getRepository().getBasePath().resolve(lrm.getPathForLocalArtifact(artifact));
223
224 artifactInstalling(session, trace, artifact, dstPath);
225
226 Exception exception = null;
227 try {
228 if (dstPath.equals(srcPath)) {
229 throw new IllegalStateException("cannot install " + dstPath + " to same path");
230 }
231
232 pathProcessor.copy(srcPath, dstPath);
233 Files.setLastModifiedTime(dstPath, Files.getLastModifiedTime(srcPath));
234 lrm.add(session, new LocalArtifactRegistration(artifact));
235 } catch (Exception e) {
236 exception = e;
237 throw new InstallationException("Failed to install artifact " + artifact + ": " + e.getMessage(), e);
238 } finally {
239 artifactInstalled(session, trace, artifact, dstPath, exception);
240 }
241 }
242
243 private void install(RepositorySystemSession session, RequestTrace trace, Metadata metadata)
244 throws InstallationException {
245 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
246
247 Path dstPath = lrm.getRepository().getBasePath().resolve(lrm.getPathForLocalMetadata(metadata));
248
249 metadataInstalling(session, trace, metadata, dstPath);
250
251 Exception exception = null;
252 try {
253 if (metadata instanceof MergeableMetadata) {
254 ((MergeableMetadata) metadata).merge(dstPath, dstPath);
255 } else {
256 if (dstPath.equals(metadata.getPath())) {
257 throw new IllegalStateException("cannot install " + dstPath + " to same path");
258 }
259 pathProcessor.copy(metadata.getPath(), dstPath);
260 }
261
262 lrm.add(session, new LocalMetadataRegistration(metadata));
263 } catch (Exception e) {
264 exception = e;
265 throw new InstallationException("Failed to install metadata " + metadata + ": " + e.getMessage(), e);
266 } finally {
267 metadataInstalled(session, trace, metadata, dstPath, exception);
268 }
269 }
270
271 private void artifactInstalling(
272 RepositorySystemSession session, RequestTrace trace, Artifact artifact, Path dstPath) {
273 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_INSTALLING);
274 event.setTrace(trace);
275 event.setArtifact(artifact);
276 event.setRepository(session.getLocalRepositoryManager().getRepository());
277 event.setPath(dstPath);
278
279 repositoryEventDispatcher.dispatch(event.build());
280 }
281
282 private void artifactInstalled(
283 RepositorySystemSession session, RequestTrace trace, Artifact artifact, Path dstPath, Exception exception) {
284 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_INSTALLED);
285 event.setTrace(trace);
286 event.setArtifact(artifact);
287 event.setRepository(session.getLocalRepositoryManager().getRepository());
288 event.setPath(dstPath);
289 event.setException(exception);
290
291 repositoryEventDispatcher.dispatch(event.build());
292 }
293
294 private void metadataInstalling(
295 RepositorySystemSession session, RequestTrace trace, Metadata metadata, Path dstPath) {
296 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.METADATA_INSTALLING);
297 event.setTrace(trace);
298 event.setMetadata(metadata);
299 event.setRepository(session.getLocalRepositoryManager().getRepository());
300 event.setPath(dstPath);
301
302 repositoryEventDispatcher.dispatch(event.build());
303 }
304
305 private void metadataInstalled(
306 RepositorySystemSession session, RequestTrace trace, Metadata metadata, Path dstPath, Exception exception) {
307 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.METADATA_INSTALLED);
308 event.setTrace(trace);
309 event.setMetadata(metadata);
310 event.setRepository(session.getLocalRepositoryManager().getRepository());
311 event.setPath(dstPath);
312 event.setException(exception);
313
314 repositoryEventDispatcher.dispatch(event.build());
315 }
316 }