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.io.File;
26 import java.io.InputStream;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.IdentityHashMap;
30 import java.util.List;
31 import java.util.ListIterator;
32 import java.util.Set;
33
34 import org.eclipse.aether.RepositoryEvent;
35 import org.eclipse.aether.RepositoryEvent.EventType;
36 import org.eclipse.aether.RepositorySystemSession;
37 import org.eclipse.aether.RequestTrace;
38 import org.eclipse.aether.SyncContext;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.impl.Installer;
41 import org.eclipse.aether.impl.MetadataGenerator;
42 import org.eclipse.aether.impl.MetadataGeneratorFactory;
43 import org.eclipse.aether.impl.RepositoryEventDispatcher;
44 import org.eclipse.aether.installation.InstallRequest;
45 import org.eclipse.aether.installation.InstallResult;
46 import org.eclipse.aether.installation.InstallationException;
47 import org.eclipse.aether.metadata.MergeableMetadata;
48 import org.eclipse.aether.metadata.Metadata;
49 import org.eclipse.aether.repository.LocalArtifactRegistration;
50 import org.eclipse.aether.repository.LocalMetadataRegistration;
51 import org.eclipse.aether.repository.LocalRepositoryManager;
52 import org.eclipse.aether.spi.io.FileProcessor;
53 import org.eclipse.aether.spi.locator.Service;
54 import org.eclipse.aether.spi.locator.ServiceLocator;
55 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
56 import org.eclipse.aether.transform.FileTransformer;
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, Service {
67
68 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultInstaller.class);
69
70 private FileProcessor fileProcessor;
71
72 private RepositoryEventDispatcher repositoryEventDispatcher;
73
74 private Collection<MetadataGeneratorFactory> metadataFactories = new ArrayList<>();
75
76 private SyncContextFactory syncContextFactory;
77
78 @Deprecated
79 public DefaultInstaller() {
80
81 }
82
83 @Inject
84 public DefaultInstaller(
85 FileProcessor fileProcessor,
86 RepositoryEventDispatcher repositoryEventDispatcher,
87 Set<MetadataGeneratorFactory> metadataFactories,
88 SyncContextFactory syncContextFactory) {
89 setFileProcessor(fileProcessor);
90 setRepositoryEventDispatcher(repositoryEventDispatcher);
91 setMetadataGeneratorFactories(metadataFactories);
92 setSyncContextFactory(syncContextFactory);
93 }
94
95 public void initService(ServiceLocator locator) {
96 setFileProcessor(locator.getService(FileProcessor.class));
97 setRepositoryEventDispatcher(locator.getService(RepositoryEventDispatcher.class));
98 setMetadataGeneratorFactories(locator.getServices(MetadataGeneratorFactory.class));
99 setSyncContextFactory(locator.getService(SyncContextFactory.class));
100 }
101
102 public DefaultInstaller setFileProcessor(FileProcessor fileProcessor) {
103 this.fileProcessor = requireNonNull(fileProcessor, "file processor cannot be null");
104 return this;
105 }
106
107 public DefaultInstaller setRepositoryEventDispatcher(RepositoryEventDispatcher repositoryEventDispatcher) {
108 this.repositoryEventDispatcher =
109 requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
110 return this;
111 }
112
113 public DefaultInstaller addMetadataGeneratorFactory(MetadataGeneratorFactory factory) {
114 metadataFactories.add(requireNonNull(factory, "metadata generator factory cannot be null"));
115 return this;
116 }
117
118 public DefaultInstaller setMetadataGeneratorFactories(Collection<MetadataGeneratorFactory> metadataFactories) {
119 if (metadataFactories == null) {
120 this.metadataFactories = new ArrayList<>();
121 } else {
122 this.metadataFactories = metadataFactories;
123 }
124 return this;
125 }
126
127 public DefaultInstaller setSyncContextFactory(SyncContextFactory syncContextFactory) {
128 this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
129 return this;
130 }
131
132 public InstallResult install(RepositorySystemSession session, InstallRequest request) throws InstallationException {
133 requireNonNull(session, "session cannot be null");
134 requireNonNull(request, "request cannot be null");
135 try (SyncContext syncContext = syncContextFactory.newInstance(session, false)) {
136 return install(syncContext, session, request);
137 }
138 }
139
140 private InstallResult install(SyncContext syncContext, RepositorySystemSession session, InstallRequest request)
141 throws InstallationException {
142 InstallResult result = new InstallResult(request);
143
144 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
145
146 List<? extends MetadataGenerator> generators = getMetadataGenerators(session, request);
147
148 List<Artifact> artifacts = new ArrayList<>(request.getArtifacts());
149
150 IdentityHashMap<Metadata, Object> processedMetadata = new IdentityHashMap<>();
151
152 List<Metadata> metadatas = Utils.prepareMetadata(generators, artifacts);
153
154 syncContext.acquire(artifacts, Utils.combine(request.getMetadata(), metadatas));
155
156 for (Metadata metadata : metadatas) {
157 install(session, trace, metadata);
158 processedMetadata.put(metadata, null);
159 result.addMetadata(metadata);
160 }
161
162 for (ListIterator<Artifact> iterator = artifacts.listIterator(); iterator.hasNext(); ) {
163 Artifact artifact = iterator.next();
164
165 for (MetadataGenerator generator : generators) {
166 artifact = generator.transformArtifact(artifact);
167 }
168
169 iterator.set(artifact);
170
171 install(session, trace, artifact);
172 result.addArtifact(artifact);
173 }
174
175 metadatas = Utils.finishMetadata(generators, artifacts);
176
177 syncContext.acquire(null, metadatas);
178
179 for (Metadata metadata : metadatas) {
180 install(session, trace, metadata);
181 processedMetadata.put(metadata, null);
182 result.addMetadata(metadata);
183 }
184
185 for (Metadata metadata : request.getMetadata()) {
186 if (!processedMetadata.containsKey(metadata)) {
187 install(session, trace, metadata);
188 result.addMetadata(metadata);
189 }
190 }
191
192 return result;
193 }
194
195 private List<? extends MetadataGenerator> getMetadataGenerators(
196 RepositorySystemSession session, InstallRequest request) {
197 PrioritizedComponents<MetadataGeneratorFactory> factories =
198 Utils.sortMetadataGeneratorFactories(session, this.metadataFactories);
199
200 List<MetadataGenerator> generators = new ArrayList<>();
201
202 for (PrioritizedComponent<MetadataGeneratorFactory> factory : factories.getEnabled()) {
203 MetadataGenerator generator = factory.getComponent().newInstance(session, request);
204 if (generator != null) {
205 generators.add(generator);
206 }
207 }
208
209 return generators;
210 }
211
212 private void install(RepositorySystemSession session, RequestTrace trace, Artifact artifact)
213 throws InstallationException {
214 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
215
216 File srcFile = artifact.getFile();
217
218 Collection<FileTransformer> fileTransformers =
219 session.getFileTransformerManager().getTransformersForArtifact(artifact);
220 if (fileTransformers.isEmpty()) {
221 install(session, trace, artifact, lrm, srcFile, null);
222 } else {
223 for (FileTransformer fileTransformer : fileTransformers) {
224 install(session, trace, artifact, lrm, srcFile, fileTransformer);
225 }
226 }
227 }
228
229 private void install(
230 RepositorySystemSession session,
231 RequestTrace trace,
232 Artifact artifact,
233 LocalRepositoryManager lrm,
234 File srcFile,
235 FileTransformer fileTransformer)
236 throws InstallationException {
237 final Artifact targetArtifact;
238 if (fileTransformer != null) {
239 targetArtifact = fileTransformer.transformArtifact(artifact);
240 } else {
241 targetArtifact = artifact;
242 }
243
244 File dstFile = new File(lrm.getRepository().getBasedir(), lrm.getPathForLocalArtifact(targetArtifact));
245
246 artifactInstalling(session, trace, targetArtifact, dstFile);
247
248 Exception exception = null;
249 try {
250 if (dstFile.equals(srcFile)) {
251 throw new IllegalStateException("cannot install " + dstFile + " to same path");
252 }
253
254 boolean copy = "pom".equals(targetArtifact.getExtension())
255 || srcFile.lastModified() != dstFile.lastModified()
256 || srcFile.length() != dstFile.length()
257 || !srcFile.exists();
258
259 if (!copy) {
260 LOGGER.debug("Skipped re-installing {} to {}, seems unchanged", srcFile, dstFile);
261 } else if (fileTransformer != null) {
262 try (InputStream is = fileTransformer.transformData(srcFile)) {
263 fileProcessor.write(dstFile, is);
264 dstFile.setLastModified(srcFile.lastModified());
265 }
266 } else {
267 fileProcessor.copy(srcFile, dstFile);
268 dstFile.setLastModified(srcFile.lastModified());
269 }
270
271 lrm.add(session, new LocalArtifactRegistration(targetArtifact));
272 } catch (Exception e) {
273 exception = e;
274 throw new InstallationException("Failed to install artifact " + targetArtifact + ": " + e.getMessage(), e);
275 } finally {
276 artifactInstalled(session, trace, targetArtifact, dstFile, exception);
277 }
278 }
279
280 private void install(RepositorySystemSession session, RequestTrace trace, Metadata metadata)
281 throws InstallationException {
282 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
283
284 File dstFile = new File(lrm.getRepository().getBasedir(), lrm.getPathForLocalMetadata(metadata));
285
286 metadataInstalling(session, trace, metadata, dstFile);
287
288 Exception exception = null;
289 try {
290 if (metadata instanceof MergeableMetadata) {
291 ((MergeableMetadata) metadata).merge(dstFile, dstFile);
292 } else {
293 if (dstFile.equals(metadata.getFile())) {
294 throw new IllegalStateException("cannot install " + dstFile + " to same path");
295 }
296 fileProcessor.copy(metadata.getFile(), dstFile);
297 }
298
299 lrm.add(session, new LocalMetadataRegistration(metadata));
300 } catch (Exception e) {
301 exception = e;
302 throw new InstallationException("Failed to install metadata " + metadata + ": " + e.getMessage(), e);
303 } finally {
304 metadataInstalled(session, trace, metadata, dstFile, exception);
305 }
306 }
307
308 private void artifactInstalling(
309 RepositorySystemSession session, RequestTrace trace, Artifact artifact, File dstFile) {
310 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_INSTALLING);
311 event.setTrace(trace);
312 event.setArtifact(artifact);
313 event.setRepository(session.getLocalRepositoryManager().getRepository());
314 event.setFile(dstFile);
315
316 repositoryEventDispatcher.dispatch(event.build());
317 }
318
319 private void artifactInstalled(
320 RepositorySystemSession session, RequestTrace trace, Artifact artifact, File dstFile, Exception exception) {
321 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_INSTALLED);
322 event.setTrace(trace);
323 event.setArtifact(artifact);
324 event.setRepository(session.getLocalRepositoryManager().getRepository());
325 event.setFile(dstFile);
326 event.setException(exception);
327
328 repositoryEventDispatcher.dispatch(event.build());
329 }
330
331 private void metadataInstalling(
332 RepositorySystemSession session, RequestTrace trace, Metadata metadata, File dstFile) {
333 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.METADATA_INSTALLING);
334 event.setTrace(trace);
335 event.setMetadata(metadata);
336 event.setRepository(session.getLocalRepositoryManager().getRepository());
337 event.setFile(dstFile);
338
339 repositoryEventDispatcher.dispatch(event.build());
340 }
341
342 private void metadataInstalled(
343 RepositorySystemSession session, RequestTrace trace, Metadata metadata, File dstFile, Exception exception) {
344 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.METADATA_INSTALLED);
345 event.setTrace(trace);
346 event.setMetadata(metadata);
347 event.setRepository(session.getLocalRepositoryManager().getRepository());
348 event.setFile(dstFile);
349 event.setException(exception);
350
351 repositoryEventDispatcher.dispatch(event.build());
352 }
353 }