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