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