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