1 package org.apache.maven.plugins.install;
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.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.OutputStream;
28 import java.io.Reader;
29 import java.io.Writer;
30 import java.util.Enumeration;
31 import java.util.jar.JarEntry;
32 import java.util.jar.JarFile;
33 import java.util.regex.Pattern;
34
35 import org.apache.maven.artifact.Artifact;
36 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
37 import org.apache.maven.model.Model;
38 import org.apache.maven.model.Parent;
39 import org.apache.maven.model.building.ModelBuildingException;
40 import org.apache.maven.model.building.ModelSource;
41 import org.apache.maven.model.building.StringModelSource;
42 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
43 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
44 import org.apache.maven.plugin.MojoExecutionException;
45 import org.apache.maven.plugin.MojoFailureException;
46 import org.apache.maven.plugins.annotations.Component;
47 import org.apache.maven.plugins.annotations.Mojo;
48 import org.apache.maven.plugins.annotations.Parameter;
49 import org.apache.maven.project.DefaultProjectBuildingRequest;
50 import org.apache.maven.project.MavenProject;
51 import org.apache.maven.project.MavenProjectHelper;
52 import org.apache.maven.project.ProjectBuilder;
53 import org.apache.maven.project.ProjectBuildingException;
54 import org.apache.maven.project.ProjectBuildingRequest;
55 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
56 import org.apache.maven.shared.transfer.project.install.ProjectInstaller;
57 import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest;
58 import org.apache.maven.shared.utils.Os;
59 import org.apache.maven.shared.utils.ReaderFactory;
60 import org.apache.maven.shared.utils.WriterFactory;
61 import org.apache.maven.shared.utils.io.IOUtil;
62 import org.codehaus.plexus.util.FileUtils;
63 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
64
65
66
67
68
69
70 @Mojo( name = "install-file", requiresProject = false, aggregator = true, threadSafe = true )
71 public class InstallFileMojo
72 extends AbstractInstallMojo
73 {
74
75
76
77
78
79 @Parameter( property = "groupId" )
80 private String groupId;
81
82
83
84
85
86 @Parameter( property = "artifactId" )
87 private String artifactId;
88
89
90
91
92
93 @Parameter( property = "version" )
94 private String version;
95
96
97
98
99
100 @Parameter( property = "packaging" )
101 private String packaging;
102
103
104
105
106
107
108
109 @Parameter( property = "classifier" )
110 private String classifier;
111
112
113
114
115 @Parameter( property = "file", required = true )
116 private File file;
117
118
119
120
121
122
123 @Parameter( property = "javadoc" )
124 private File javadoc;
125
126
127
128
129
130
131 @Parameter( property = "sources" )
132 private File sources;
133
134
135
136
137
138
139
140 @Parameter( property = "pomFile" )
141 private File pomFile;
142
143
144
145
146
147
148
149 @Parameter( property = "generatePom" )
150 private Boolean generatePom;
151
152
153
154
155
156
157
158 @Parameter( property = "localRepositoryPath" )
159 private File localRepositoryPath;
160
161
162
163
164 @Component
165 private MavenProjectHelper projectHelper;
166
167
168
169
170 @Component
171 private ProjectBuilder projectBuilder;
172
173
174
175
176 @Component
177 private ProjectInstaller installer;
178
179
180
181
182 public void execute()
183 throws MojoExecutionException, MojoFailureException
184 {
185
186 if ( !file.exists() )
187 {
188 String message = "The specified file '" + file.getPath() + "' not exists";
189 getLog().error( message );
190 throw new MojoFailureException( message );
191 }
192
193 ProjectBuildingRequest buildingRequest = session.getProjectBuildingRequest();
194
195
196
197
198 if ( localRepositoryPath != null )
199 {
200 buildingRequest = repositoryManager.setLocalRepositoryBasedir( buildingRequest, localRepositoryPath );
201
202 getLog().debug( "localRepoPath: " + repositoryManager.getLocalRepositoryBasedir( buildingRequest ) );
203 }
204
205 File temporaryPom = null;
206
207 if ( pomFile != null )
208 {
209 processModel( readModel( pomFile ) );
210 }
211 else
212 {
213 temporaryPom = readingPomFromJarFile();
214 pomFile = temporaryPom;
215 }
216
217 MavenProject project = createMavenProject();
218
219
220
221
222 DefaultArtifactHandler ah = new DefaultArtifactHandler( packaging );
223 ah.setExtension( FileUtils.getExtension( file.getName() ) );
224
225 project.getArtifact().setArtifactHandler( ah );
226 Artifact artifact = project.getArtifact();
227
228 if ( file.equals( getLocalRepoFile( buildingRequest, artifact ) ) )
229 {
230 throw new MojoFailureException( "Cannot install artifact. "
231 + "Artifact is already in the local repository.\n\nFile in question is: " + file + "\n" );
232 }
233
234 if ( classifier == null )
235 {
236 artifact.setFile( file );
237 if ( "pom".equals( packaging ) )
238 {
239 project.setFile( file );
240 }
241 }
242 else
243 {
244 projectHelper.attachArtifact( project, packaging, classifier, file );
245 }
246
247 if ( !"pom".equals( packaging ) )
248 {
249 if ( pomFile != null )
250 {
251 if ( classifier == null )
252 {
253 artifact.addMetadata( new ProjectArtifactMetadata( artifact, pomFile ) );
254 }
255 else
256 {
257 project.setFile( pomFile );
258 }
259 }
260 else
261 {
262 temporaryPom = generatePomFile();
263 ProjectArtifactMetadata pomMetadata = new ProjectArtifactMetadata( artifact, temporaryPom );
264 if ( Boolean.TRUE.equals( generatePom )
265 || ( generatePom == null && !getLocalRepoFile( buildingRequest, pomMetadata ).exists() ) )
266 {
267 getLog().debug( "Installing generated POM" );
268 if ( classifier == null )
269 {
270 artifact.addMetadata( pomMetadata );
271 }
272 else
273 {
274 project.setFile( temporaryPom );
275 }
276 }
277 else if ( generatePom == null )
278 {
279 getLog().debug( "Skipping installation of generated POM, already present in local repository" );
280 }
281 }
282 }
283
284 if ( sources != null )
285 {
286 projectHelper.attachArtifact( project, "jar", "sources", sources );
287 }
288
289 if ( javadoc != null )
290 {
291 projectHelper.attachArtifact( project, "jar", "javadoc", javadoc );
292 }
293
294 try
295 {
296
297 ProjectInstallerRequest projectInstallerRequest =
298 new ProjectInstallerRequest().setProject( project );
299
300
301 installer.install( buildingRequest, projectInstallerRequest );
302 }
303 catch ( Exception e )
304 {
305 throw new MojoExecutionException( e.getMessage(), e );
306 }
307 finally
308 {
309 if ( temporaryPom != null )
310 {
311
312 temporaryPom.delete();
313 }
314 }
315 }
316
317
318
319
320
321
322
323
324
325
326 private MavenProject createMavenProject()
327 throws MojoExecutionException, MojoFailureException
328 {
329 if ( groupId == null || artifactId == null || version == null || packaging == null )
330 {
331 throw new MojoExecutionException( "The artifact information is incomplete: 'groupId', 'artifactId', "
332 + "'version' and 'packaging' are required." );
333 }
334 ModelSource modelSource = new StringModelSource( "<project><modelVersion>4.0.0</modelVersion><groupId>"
335 + groupId + "</groupId><artifactId>" + artifactId + "</artifactId><version>" + version
336 + "</version><packaging>" + ( classifier == null ? packaging : "pom" ) + "</packaging></project>" );
337 ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
338 pbr.setProcessPlugins( false );
339 try
340 {
341 return projectBuilder.build( modelSource, pbr ).getProject();
342 }
343 catch ( ProjectBuildingException e )
344 {
345 if ( e.getCause() instanceof ModelBuildingException )
346 {
347 throw new MojoExecutionException( "The artifact information is not valid:" + Os.LINE_SEP
348 + e.getCause().getMessage() );
349 }
350 throw new MojoFailureException( "Unable to create the project.", e );
351 }
352 }
353
354 private File readingPomFromJarFile()
355 throws MojoExecutionException
356 {
357 File pomFile = null;
358
359 JarFile jarFile = null;
360 try
361 {
362 Pattern pomEntry = Pattern.compile( "META-INF/maven/.*/pom\\.xml" );
363
364 jarFile = new JarFile( file );
365
366 Enumeration<JarEntry> jarEntries = jarFile.entries();
367
368 while ( jarEntries.hasMoreElements() )
369 {
370 JarEntry entry = jarEntries.nextElement();
371
372 if ( pomEntry.matcher( entry.getName() ).matches() )
373 {
374 getLog().debug( "Using " + entry.getName() + " as pomFile" );
375
376 InputStream pomInputStream = null;
377 OutputStream pomOutputStream = null;
378
379 try
380 {
381 pomInputStream = jarFile.getInputStream( entry );
382
383 String base = file.getName();
384 if ( base.indexOf( '.' ) > 0 )
385 {
386 base = base.substring( 0, base.lastIndexOf( '.' ) );
387 }
388 pomFile = File.createTempFile( base, ".pom" );
389
390 pomOutputStream = new FileOutputStream( pomFile );
391
392 IOUtil.copy( pomInputStream, pomOutputStream );
393
394 pomOutputStream.close();
395 pomOutputStream = null;
396
397 pomInputStream.close();
398 pomInputStream = null;
399
400 processModel( readModel( pomFile ) );
401
402 break;
403 }
404 finally
405 {
406 IOUtil.close( pomInputStream );
407 IOUtil.close( pomOutputStream );
408 }
409 }
410 }
411
412 if ( pomFile == null )
413 {
414 getLog().info( "pom.xml not found in " + file.getName() );
415 }
416 }
417 catch ( IOException e )
418 {
419
420 }
421 finally
422 {
423 if ( jarFile != null )
424 {
425 try
426 {
427 jarFile.close();
428 }
429 catch ( IOException e )
430 {
431
432 }
433 }
434 }
435 return pomFile;
436 }
437
438
439
440
441
442
443
444
445 private Model readModel( File pomFile )
446 throws MojoExecutionException
447 {
448 Reader reader = null;
449 try
450 {
451 reader = ReaderFactory.newXmlReader( pomFile );
452 final Model model = new MavenXpp3Reader().read( reader );
453 reader.close();
454 reader = null;
455 return model;
456 }
457 catch ( FileNotFoundException e )
458 {
459 throw new MojoExecutionException( "File not found " + pomFile, e );
460 }
461 catch ( IOException e )
462 {
463 throw new MojoExecutionException( "Error reading POM " + pomFile, e );
464 }
465 catch ( XmlPullParserException e )
466 {
467 throw new MojoExecutionException( "Error parsing POM " + pomFile, e );
468 }
469 finally
470 {
471 IOUtil.close( reader );
472 }
473 }
474
475
476
477
478
479
480 private void processModel( Model model )
481 {
482 Parent parent = model.getParent();
483
484 if ( this.groupId == null )
485 {
486 this.groupId = model.getGroupId();
487 if ( this.groupId == null && parent != null )
488 {
489 this.groupId = parent.getGroupId();
490 }
491 }
492 if ( this.artifactId == null )
493 {
494 this.artifactId = model.getArtifactId();
495 }
496 if ( this.version == null )
497 {
498 this.version = model.getVersion();
499 if ( this.version == null && parent != null )
500 {
501 this.version = parent.getVersion();
502 }
503 }
504 if ( this.packaging == null )
505 {
506 this.packaging = model.getPackaging();
507 }
508 }
509
510
511
512
513
514
515 private Model generateModel()
516 {
517 Model model = new Model();
518
519 model.setModelVersion( "4.0.0" );
520
521 model.setGroupId( groupId );
522 model.setArtifactId( artifactId );
523 model.setVersion( version );
524 model.setPackaging( packaging );
525
526 model.setDescription( "POM was created from install:install-file" );
527
528 return model;
529 }
530
531
532
533
534
535
536
537
538 private File generatePomFile()
539 throws MojoExecutionException
540 {
541 Model model = generateModel();
542
543 Writer writer = null;
544 try
545 {
546 File pomFile = File.createTempFile( "mvninstall", ".pom" );
547
548 writer = WriterFactory.newXmlWriter( pomFile );
549 new MavenXpp3Writer().write( writer, model );
550 writer.close();
551 writer = null;
552
553 return pomFile;
554 }
555 catch ( IOException e )
556 {
557 throw new MojoExecutionException( "Error writing temporary POM file: " + e.getMessage(), e );
558 }
559 finally
560 {
561 IOUtil.close( writer );
562 }
563 }
564
565 }