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<MetadataGeneratorFactory>();
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, "repository event dispatcher cannot be null" );
110 return this;
111 }
112
113 public DefaultInstaller addMetadataGeneratorFactory( MetadataGeneratorFactory factory )
114 {
115 metadataFactories.add( requireNonNull( factory, "metadata generator factory cannot be null" ) );
116 return this;
117 }
118
119 public DefaultInstaller setMetadataGeneratorFactories( Collection<MetadataGeneratorFactory> metadataFactories )
120 {
121 if ( metadataFactories == null )
122 {
123 this.metadataFactories = new ArrayList<MetadataGeneratorFactory>();
124 }
125 else
126 {
127 this.metadataFactories = metadataFactories;
128 }
129 return this;
130 }
131
132 public DefaultInstaller setSyncContextFactory( SyncContextFactory syncContextFactory )
133 {
134 this.syncContextFactory = requireNonNull( syncContextFactory, "sync context factory cannot be null" );
135 return this;
136 }
137
138 public InstallResult install( RepositorySystemSession session, InstallRequest request )
139 throws InstallationException
140 {
141 SyncContext syncContext = syncContextFactory.newInstance( session, false );
142
143 try
144 {
145 return install( syncContext, session, request );
146 }
147 finally
148 {
149 syncContext.close();
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<Artifact>( request.getArtifacts() );
163
164 IdentityHashMap<Metadata, Object> processedMetadata = new IdentityHashMap<Metadata, Object>();
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 ( int i = 0; i < artifacts.size(); i++ )
178 {
179 Artifact artifact = artifacts.get( i );
180
181 for ( MetadataGenerator generator : generators )
182 {
183 artifact = generator.transformArtifact( artifact );
184 }
185
186 artifacts.set( i, 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<MetadataGenerator>();
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().getTransformersForArtifact( artifact );
243 if ( fileTransformers.isEmpty() )
244 {
245 install( session, trace, artifact, lrm, srcFile, null );
246 }
247 else
248 {
249 for ( FileTransformer fileTransformer : fileTransformers )
250 {
251 install( session, trace, artifact, lrm, srcFile, fileTransformer );
252 }
253 }
254 }
255
256 private void install( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
257 LocalRepositoryManager lrm, File srcFile, FileTransformer fileTransformer )
258 throws InstallationException
259 {
260 final Artifact targetArtifact;
261 if ( fileTransformer != null )
262 {
263 targetArtifact = fileTransformer.transformArtifact( artifact );
264 }
265 else
266 {
267 targetArtifact = artifact;
268 }
269
270 File dstFile = new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalArtifact( targetArtifact ) );
271
272 artifactInstalling( session, trace, targetArtifact, dstFile );
273
274 Exception exception = null;
275 try
276 {
277 if ( dstFile.equals( srcFile ) )
278 {
279 throw new IllegalStateException( "cannot install " + dstFile + " to same path" );
280 }
281
282 boolean copy =
283 "pom".equals( targetArtifact.getExtension() ) || srcFile.lastModified() != dstFile.lastModified()
284 || srcFile.length() != dstFile.length() || !srcFile.exists();
285
286 if ( !copy )
287 {
288 LOGGER.debug( "Skipped re-installing {} to {}, seems unchanged", srcFile, dstFile );
289 }
290 else if ( fileTransformer != null )
291 {
292 try ( InputStream is = fileTransformer.transformData( srcFile ) )
293 {
294 fileProcessor.write( dstFile, is );
295 dstFile.setLastModified( srcFile.lastModified() );
296 }
297 }
298 else
299 {
300 fileProcessor.copy( srcFile, dstFile );
301 dstFile.setLastModified( srcFile.lastModified() );
302 }
303
304 lrm.add( session, new LocalArtifactRegistration( targetArtifact ) );
305 }
306 catch ( Exception e )
307 {
308 exception = e;
309 throw new InstallationException( "Failed to install artifact " + targetArtifact + ": " + e.getMessage(), e );
310 }
311 finally
312 {
313 artifactInstalled( session, trace, targetArtifact, dstFile, exception );
314 }
315 }
316
317 private void install( RepositorySystemSession session, RequestTrace trace, Metadata metadata )
318 throws InstallationException
319 {
320 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
321
322 File dstFile = new File( lrm.getRepository().getBasedir(), lrm.getPathForLocalMetadata( metadata ) );
323
324 metadataInstalling( session, trace, metadata, dstFile );
325
326 Exception exception = null;
327 try
328 {
329 if ( metadata instanceof MergeableMetadata )
330 {
331 ( (MergeableMetadata) metadata ).merge( dstFile, dstFile );
332 }
333 else
334 {
335 if ( dstFile.equals( metadata.getFile() ) )
336 {
337 throw new IllegalStateException( "cannot install " + dstFile + " to same path" );
338 }
339 fileProcessor.copy( metadata.getFile(), dstFile );
340 }
341
342 lrm.add( session, new LocalMetadataRegistration( metadata ) );
343 }
344 catch ( Exception e )
345 {
346 exception = e;
347 throw new InstallationException( "Failed to install metadata " + metadata + ": " + e.getMessage(), e );
348 }
349 finally
350 {
351 metadataInstalled( session, trace, metadata, dstFile, exception );
352 }
353 }
354
355 private void artifactInstalling( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
356 File dstFile )
357 {
358 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_INSTALLING );
359 event.setTrace( trace );
360 event.setArtifact( artifact );
361 event.setRepository( session.getLocalRepositoryManager().getRepository() );
362 event.setFile( dstFile );
363
364 repositoryEventDispatcher.dispatch( event.build() );
365 }
366
367 private void artifactInstalled( RepositorySystemSession session, RequestTrace trace, Artifact artifact,
368 File dstFile, Exception exception )
369 {
370 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_INSTALLED );
371 event.setTrace( trace );
372 event.setArtifact( artifact );
373 event.setRepository( session.getLocalRepositoryManager().getRepository() );
374 event.setFile( dstFile );
375 event.setException( exception );
376
377 repositoryEventDispatcher.dispatch( event.build() );
378 }
379
380 private void metadataInstalling( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
381 File dstFile )
382 {
383 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INSTALLING );
384 event.setTrace( trace );
385 event.setMetadata( metadata );
386 event.setRepository( session.getLocalRepositoryManager().getRepository() );
387 event.setFile( dstFile );
388
389 repositoryEventDispatcher.dispatch( event.build() );
390 }
391
392 private void metadataInstalled( RepositorySystemSession session, RequestTrace trace, Metadata metadata,
393 File dstFile, Exception exception )
394 {
395 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.METADATA_INSTALLED );
396 event.setTrace( trace );
397 event.setMetadata( metadata );
398 event.setRepository( session.getLocalRepositoryManager().getRepository() );
399 event.setFile( dstFile );
400 event.setException( exception );
401
402 repositoryEventDispatcher.dispatch( event.build() );
403 }
404
405 }