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