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