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