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