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