1 package org.eclipse.aether.internal.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static java.util.Objects.requireNonNull;
23
24 import java.io.File;
25 import java.io.InputStream;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.IdentityHashMap;
29 import java.util.List;
30 import java.util.ListIterator;
31 import java.util.Set;
32
33 import javax.inject.Inject;
34 import javax.inject.Named;
35 import javax.inject.Singleton;
36
37 import org.eclipse.aether.RepositoryEvent;
38 import org.eclipse.aether.RepositoryEvent.EventType;
39 import org.eclipse.aether.RepositorySystemSession;
40 import org.eclipse.aether.RequestTrace;
41 import org.eclipse.aether.SyncContext;
42 import org.eclipse.aether.artifact.Artifact;
43 import org.eclipse.aether.impl.Installer;
44 import org.eclipse.aether.impl.MetadataGenerator;
45 import org.eclipse.aether.impl.MetadataGeneratorFactory;
46 import org.eclipse.aether.impl.RepositoryEventDispatcher;
47 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
48 import org.eclipse.aether.installation.InstallRequest;
49 import org.eclipse.aether.installation.InstallResult;
50 import org.eclipse.aether.installation.InstallationException;
51 import org.eclipse.aether.metadata.MergeableMetadata;
52 import org.eclipse.aether.metadata.Metadata;
53 import org.eclipse.aether.repository.LocalArtifactRegistration;
54 import org.eclipse.aether.repository.LocalMetadataRegistration;
55 import org.eclipse.aether.repository.LocalRepositoryManager;
56 import org.eclipse.aether.spi.io.FileProcessor;
57 import org.eclipse.aether.spi.locator.Service;
58 import org.eclipse.aether.spi.locator.ServiceLocator;
59 import org.eclipse.aether.transform.FileTransformer;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63
64
65 @Singleton
66 @Named
67 public class DefaultInstaller
68 implements Installer, Service
69 {
70
71 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultInstaller.class );
72
73 private FileProcessor fileProcessor;
74
75 private RepositoryEventDispatcher repositoryEventDispatcher;
76
77 private Collection<MetadataGeneratorFactory> metadataFactories = new ArrayList<>();
78
79 private SyncContextFactory syncContextFactory;
80
81 public DefaultInstaller()
82 {
83
84 }
85
86 @Inject
87 DefaultInstaller( FileProcessor fileProcessor, RepositoryEventDispatcher repositoryEventDispatcher,
88 Set<MetadataGeneratorFactory> metadataFactories, SyncContextFactory syncContextFactory )
89 {
90 setFileProcessor( fileProcessor );
91 setRepositoryEventDispatcher( repositoryEventDispatcher );
92 setMetadataGeneratorFactories( metadataFactories );
93 setSyncContextFactory( syncContextFactory );
94 }
95
96 public void initService( ServiceLocator locator )
97 {
98 setFileProcessor( locator.getService( FileProcessor.class ) );
99 setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) );
100 setMetadataGeneratorFactories( locator.getServices( MetadataGeneratorFactory.class ) );
101 setSyncContextFactory( locator.getService( SyncContextFactory.class ) );
102 }
103
104 public DefaultInstaller setFileProcessor( FileProcessor fileProcessor )
105 {
106 this.fileProcessor = requireNonNull( fileProcessor, "file processor cannot be null" );
107 return this;
108 }
109
110 public DefaultInstaller setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher )
111 {
112 this.repositoryEventDispatcher = requireNonNull( repositoryEventDispatcher,
113 "repository event dispatcher cannot be null" );
114 return this;
115 }
116
117 public DefaultInstaller addMetadataGeneratorFactory( MetadataGeneratorFactory factory )
118 {
119 metadataFactories.add( requireNonNull( factory, "metadata generator factory cannot be null" ) );
120 return this;
121 }
122
123 public DefaultInstaller setMetadataGeneratorFactories( Collection<MetadataGeneratorFactory> metadataFactories )
124 {
125 if ( metadataFactories == null )
126 {
127 this.metadataFactories = new ArrayList<>();
128 }
129 else
130 {
131 this.metadataFactories = metadataFactories;
132 }
133 return this;
134 }
135
136 public DefaultInstaller setSyncContextFactory( SyncContextFactory syncContextFactory )
137 {
138 this.syncContextFactory = requireNonNull( syncContextFactory, "sync context factory cannot be null" );
139 return this;
140 }
141
142 public InstallResult install( RepositorySystemSession session, InstallRequest request )
143 throws InstallationException
144 {
145 requireNonNull( session, "session cannot be null" );
146 requireNonNull( request, "request cannot be null" );
147 try ( SyncContext syncContext = syncContextFactory.newInstance( session, false ) )
148 {
149 return install( syncContext, session, request );
150 }
151 }
152
153 private InstallResult install( SyncContext syncContext, RepositorySystemSession session, InstallRequest request )
154 throws InstallationException
155 {
156 InstallResult result = new InstallResult( request );
157
158 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request );
159
160 List<? extends MetadataGenerator> generators = getMetadataGenerators( session, request );
161
162 List<Artifact> artifacts = new ArrayList<>( request.getArtifacts() );
163
164 IdentityHashMap<Metadata, Object> processedMetadata = new IdentityHashMap<>();
165
166 List<Metadata> metadatas = Utils.prepareMetadata( generators, artifacts );
167
168 syncContext.acquire( artifacts, Utils.combine( request.getMetadata(), metadatas ) );
169
170 for ( Metadata metadata : metadatas )
171 {
172 install( session, trace, metadata );
173 processedMetadata.put( metadata, null );
174 result.addMetadata( metadata );
175 }
176
177 for ( ListIterator<Artifact> iterator = artifacts.listIterator(); iterator.hasNext(); )
178 {
179 Artifact artifact = iterator.next();
180
181 for ( MetadataGenerator generator : generators )
182 {
183 artifact = generator.transformArtifact( artifact );
184 }
185
186 iterator.set( artifact );
187
188 install( session, trace, artifact );
189 result.addArtifact( artifact );
190 }
191
192 metadatas = Utils.finishMetadata( generators, artifacts );
193
194 syncContext.acquire( null, metadatas );
195
196 for ( Metadata metadata : metadatas )
197 {
198 install( session, trace, metadata );
199 processedMetadata.put( metadata, null );
200 result.addMetadata( metadata );
201 }
202
203 for ( Metadata metadata : request.getMetadata() )
204 {
205 if ( !processedMetadata.containsKey( metadata ) )
206 {
207 install( session, trace, metadata );
208 result.addMetadata( metadata );
209 }
210 }
211
212 return result;
213 }
214
215 private List<? extends MetadataGenerator> getMetadataGenerators( RepositorySystemSession session,
216 InstallRequest request )
217 {
218 PrioritizedComponents<MetadataGeneratorFactory> factories =
219 Utils.sortMetadataGeneratorFactories( session, this.metadataFactories );
220
221 List<MetadataGenerator> generators = new ArrayList<>();
222
223 for ( PrioritizedComponent<MetadataGeneratorFactory> factory : factories.getEnabled() )
224 {
225 MetadataGenerator generator = factory.getComponent().newInstance( session, request );
226 if ( generator != null )
227 {
228 generators.add( generator );
229 }
230 }
231
232 return generators;
233 }
234
235 private void install( RepositorySystemSession session, RequestTrace trace, Artifact artifact )
236 throws InstallationException
237 {
238 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
239
240 File srcFile = artifact.getFile();
241
242 Collection<FileTransformer> fileTransformers = session.getFileTransformerManager()
243 .getTransformersForArtifact( artifact );
244 if ( fileTransformers.isEmpty() )
245 {
246 install( session, trace, artifact, lrm, srcFile, null );
247 }
248 else
249 {
250 for ( FileTransformer fileTransformer : fileTransformers )
251 {
252 install( session, trace, artifact, lrm, srcFile, fileTransformer );
253 }
254 }
255 }
256
257 private void install( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
258 LocalRepositoryManager lrm, File srcFile, FileTransformer fileTransformer )
259 throws InstallationException
260 {
261 final Artifact targetArtifact;
262 if ( fileTransformer != null )
263 {
264 targetArtifact = fileTransformer.transformArtifact( artifact );
265 }
266 else
267 {
268 targetArtifact = artifact;
269 }
270
271 File dstFile = new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalArtifact( targetArtifact ) );
272
273 artifactInstalling( session, trace, targetArtifact, dstFile );
274
275 Exception exception = null;
276 try
277 {
278 if ( dstFile.equals( srcFile ) )
279 {
280 throw new IllegalStateException( "cannot install " + dstFile + " to same path" );
281 }
282
283 boolean copy =
284 "pom".equals( targetArtifact.getExtension() ) || srcFile.lastModified() != dstFile.lastModified()
285 || srcFile.length() != dstFile.length() || !srcFile.exists();
286
287 if ( !copy )
288 {
289 LOGGER.debug( "Skipped re-installing {} to {}, seems unchanged", srcFile, dstFile );
290 }
291 else if ( fileTransformer != null )
292 {
293 try ( InputStream is = fileTransformer.transformData( srcFile ) )
294 {
295 fileProcessor.write( dstFile, is );
296 dstFile.setLastModified( srcFile.lastModified() );
297 }
298 }
299 else
300 {
301 fileProcessor.copy( srcFile, dstFile );
302 dstFile.setLastModified( srcFile.lastModified() );
303 }
304
305 lrm.add( session, new LocalArtifactRegistration( targetArtifact ) );
306 }
307 catch ( Exception e )
308 {
309 exception = e;
310 throw new InstallationException( "Failed to install artifact " + targetArtifact + ": " + e.getMessage(),
311 e );
312 }
313 finally
314 {
315 artifactInstalled( session, trace, targetArtifact, dstFile, exception );
316 }
317 }
318
319 private void install( RepositorySystemSession session, RequestTrace trace, Metadata metadata )
320 throws InstallationException
321 {
322 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
323
324 File dstFile = new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalMetadata( metadata ) );
325
326 metadataInstalling( session, trace, metadata, dstFile );
327
328 Exception exception = null;
329 try
330 {
331 if ( metadata instanceof MergeableMetadata )
332 {
333 ( (MergeableMetadata) metadata ).merge( dstFile, dstFile );
334 }
335 else
336 {
337 if ( dstFile.equals( metadata.getFile() ) )
338 {
339 throw new IllegalStateException( "cannot install " + dstFile + " to same path" );
340 }
341 fileProcessor.copy( metadata.getFile(), dstFile );
342 }
343
344 lrm.add( session, new LocalMetadataRegistration( metadata ) );
345 }
346 catch ( Exception e )
347 {
348 exception = e;
349 throw new InstallationException( "Failed to install metadata " + metadata + ": " + e.getMessage(), e );
350 }
351 finally
352 {
353 metadataInstalled( session, trace, metadata, dstFile, exception );
354 }
355 }
356
357 private void artifactInstalling( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
358 File dstFile )
359 {
360 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_INSTALLING );
361 event.setTrace( trace );
362 event.setArtifact( artifact );
363 event.setRepository( session.getLocalRepositoryManager().getRepository() );
364 event.setFile( dstFile );
365
366 repositoryEventDispatcher.dispatch( event.build() );
367 }
368
369 private void artifactInstalled( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
370 File dstFile, Exception exception )
371 {
372 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_INSTALLED );
373 event.setTrace( trace );
374 event.setArtifact( artifact );
375 event.setRepository( session.getLocalRepositoryManager().getRepository() );
376 event.setFile( dstFile );
377 event.setException( exception );
378
379 repositoryEventDispatcher.dispatch( event.build() );
380 }
381
382 private void metadataInstalling( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
383 File dstFile )
384 {
385 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INSTALLING );
386 event.setTrace( trace );
387 event.setMetadata( metadata );
388 event.setRepository( session.getLocalRepositoryManager().getRepository() );
389 event.setFile( dstFile );
390
391 repositoryEventDispatcher.dispatch( event.build() );
392 }
393
394 private void metadataInstalled( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
395 File dstFile, Exception exception )
396 {
397 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INSTALLED );
398 event.setTrace( trace );
399 event.setMetadata( metadata );
400 event.setRepository( session.getLocalRepositoryManager().getRepository() );
401 event.setFile( dstFile );
402 event.setException( exception );
403
404 repositoryEventDispatcher.dispatch( event.build() );
405 }
406
407 }