1 package org.apache.maven.plugin.deploy;
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.IOException;
25 import java.io.Reader;
26 import java.io.Writer;
27 import java.util.List;
28
29 import org.apache.maven.artifact.Artifact;
30 import org.apache.maven.artifact.deployer.ArtifactDeploymentException;
31 import org.apache.maven.artifact.metadata.ArtifactMetadata;
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
34 import org.apache.maven.model.Model;
35 import org.apache.maven.model.Parent;
36 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
37 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.MojoFailureException;
40 import org.apache.maven.plugins.annotations.Component;
41 import org.apache.maven.plugins.annotations.Mojo;
42 import org.apache.maven.plugins.annotations.Parameter;
43 import org.apache.maven.project.MavenProject;
44 import org.apache.maven.project.MavenProjectHelper;
45 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
46 import org.apache.maven.project.validation.ModelValidationResult;
47 import org.apache.maven.project.validation.ModelValidator;
48 import org.codehaus.plexus.util.FileUtils;
49 import org.codehaus.plexus.util.IOUtil;
50 import org.codehaus.plexus.util.ReaderFactory;
51 import org.codehaus.plexus.util.StringUtils;
52 import org.codehaus.plexus.util.WriterFactory;
53 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
54
55
56
57
58
59
60 @Mojo( name = "deploy-file", requiresProject = false, threadSafe = true )
61 public class DeployFileMojo
62 extends AbstractDeployMojo
63 {
64
65
66
67 @Parameter( defaultValue = "${project}", readonly = true, required = true )
68 private MavenProject project;
69
70
71
72
73 @Component
74 private MavenProjectHelper projectHelper;
75
76
77
78
79 @Parameter( property = "groupId" )
80 private String groupId;
81
82
83
84
85 @Parameter( property = "artifactId" )
86 private String artifactId;
87
88
89
90
91 @Parameter( property = "version" )
92 private String version;
93
94
95
96
97
98
99
100 @Parameter( property = "packaging" )
101 private String packaging;
102
103
104
105
106 @Parameter( property = "generatePom.description" )
107 private String description;
108
109
110
111
112 @Parameter( property = "file", required = true )
113 private File file;
114
115
116
117
118
119
120 @Parameter( property = "javadoc" )
121 private File javadoc;
122
123
124
125
126
127
128 @Parameter( property = "sources" )
129 private File sources;
130
131
132
133
134
135 @Parameter( property = "repositoryId", defaultValue = "remote-repository", required = true )
136 private String repositoryId;
137
138
139
140
141 @Parameter( property = "repositoryLayout", defaultValue = "default" )
142 private String repositoryLayout;
143
144
145
146
147
148 @Parameter( property = "url", required = true )
149 private String url;
150
151
152
153
154 @Parameter( property = "pomFile" )
155 private File pomFile;
156
157
158
159
160 @Parameter( property = "generatePom", defaultValue = "true" )
161 private boolean generatePom;
162
163
164
165
166 @Parameter( property = "classifier" )
167 private String classifier;
168
169
170
171
172 @Parameter( property = "uniqueVersion", defaultValue = "true" )
173 private boolean uniqueVersion;
174
175
176
177
178 @Component
179 private ModelValidator modelValidator;
180
181
182
183
184
185 @Parameter( property = "types" )
186 private String types;
187
188
189
190
191
192 @Parameter( property = "classifiers" )
193 private String classifiers;
194
195
196
197
198
199 @Parameter( property = "files" )
200 private String files;
201
202 void initProperties()
203 throws MojoExecutionException
204 {
205
206 if ( pomFile != null )
207 {
208 generatePom = false;
209
210 Model model = readModel( pomFile );
211
212 processModel( model );
213 }
214
215 if ( packaging == null && file != null )
216 {
217 packaging = FileUtils.getExtension( file.getName() );
218 }
219 }
220
221 public void execute()
222 throws MojoExecutionException, MojoFailureException
223 {
224 failIfOffline();
225
226 if ( !file.exists() )
227 {
228 throw new MojoExecutionException( file.getPath() + " not found." );
229 }
230
231 initProperties();
232
233 validateArtifactInformation();
234
235 ArtifactRepositoryLayout layout = getLayout( repositoryLayout );
236
237 ArtifactRepository deploymentRepository =
238 repositoryFactory.createDeploymentArtifactRepository( repositoryId, url, layout, uniqueVersion );
239
240 String protocol = deploymentRepository.getProtocol();
241
242 if ( StringUtils.isEmpty( protocol ) )
243 {
244 throw new MojoExecutionException( "No transfer protocol found." );
245 }
246
247
248 Artifact artifact =
249 artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, packaging, classifier );
250
251 if ( file.equals( getLocalRepoFile( artifact ) ) )
252 {
253 throw new MojoFailureException( "Cannot deploy artifact from the local repository: " + file );
254 }
255
256
257 if ( !"pom".equals( packaging ) )
258 {
259 if ( pomFile != null )
260 {
261 ArtifactMetadata metadata = new ProjectArtifactMetadata( artifact, pomFile );
262 artifact.addMetadata( metadata );
263 }
264 else if ( generatePom )
265 {
266 ArtifactMetadata metadata = new ProjectArtifactMetadata( artifact, generatePomFile() );
267 artifact.addMetadata( metadata );
268 }
269 }
270
271 if ( updateReleaseInfo )
272 {
273 artifact.setRelease( true );
274 }
275
276 project.setArtifact( artifact );
277
278 try
279 {
280 deploy( file, artifact, deploymentRepository, getLocalRepository(), getRetryFailedDeploymentCount() );
281 }
282 catch ( ArtifactDeploymentException e )
283 {
284 throw new MojoExecutionException( e.getMessage(), e );
285 }
286
287 if ( sources != null )
288 {
289 projectHelper.attachArtifact( project, "jar", "sources", sources );
290 }
291
292 if ( javadoc != null )
293 {
294 projectHelper.attachArtifact( project, "jar", "javadoc", javadoc );
295 }
296
297 if ( files != null )
298 {
299 if ( types == null )
300 {
301 throw new MojoExecutionException( "You must specify 'types' if you specify 'files'" );
302 }
303 if ( classifiers == null )
304 {
305 throw new MojoExecutionException( "You must specify 'classifiers' if you specify 'files'" );
306 }
307 int filesLength = StringUtils.countMatches( files, "," );
308 int typesLength = StringUtils.countMatches( types, "," );
309 int classifiersLength = StringUtils.countMatches( classifiers, "," );
310 if ( typesLength != filesLength )
311 {
312 throw new MojoExecutionException( "You must specify the same number of entries in 'files' and "
313 + "'types' (respectively " + filesLength + " and " + typesLength + " entries )" );
314 }
315 if ( classifiersLength != filesLength )
316 {
317 throw new MojoExecutionException( "You must specify the same number of entries in 'files' and "
318 + "'classifiers' (respectively " + filesLength + " and " + classifiersLength + " entries )" );
319 }
320 int fi = 0;
321 int ti = 0;
322 int ci = 0;
323 for ( int i = 0; i <= filesLength; i++ )
324 {
325 int nfi = files.indexOf( ',', fi );
326 if ( nfi == -1 )
327 {
328 nfi = files.length();
329 }
330 int nti = types.indexOf( ',', ti );
331 if ( nti == -1 )
332 {
333 nti = types.length();
334 }
335 int nci = classifiers.indexOf( ',', ci );
336 if ( nci == -1 )
337 {
338 nci = classifiers.length();
339 }
340 File file = new File( files.substring( fi, nfi ) );
341 if ( !file.isFile() )
342 {
343
344 file = new File( project.getBasedir(), files.substring( fi, nfi ) );
345 }
346 if ( file.isFile() )
347 {
348 if ( StringUtils.isWhitespace( classifiers.substring( ci, nci ) ) )
349 {
350 projectHelper.attachArtifact( project, types.substring( ti, nti ).trim(), file );
351 }
352 else
353 {
354 projectHelper.attachArtifact( project, types.substring( ti, nti ).trim(),
355 classifiers.substring( ci, nci ).trim(), file );
356 }
357 }
358 else
359 {
360 throw new MojoExecutionException( "Specified side artifact " + file + " does not exist" );
361 }
362 fi = nfi + 1;
363 ti = nti + 1;
364 ci = nci + 1;
365 }
366 }
367 else
368 {
369 if ( types != null )
370 {
371 throw new MojoExecutionException( "You must specify 'files' if you specify 'types'" );
372 }
373 if ( classifiers != null )
374 {
375 throw new MojoExecutionException( "You must specify 'files' if you specify 'classifiers'" );
376 }
377 }
378
379 @SuppressWarnings( "unchecked" )
380 List<Artifact> attachedArtifacts = project.getAttachedArtifacts();
381
382 for ( Artifact attached : attachedArtifacts )
383 {
384 try
385 {
386 deploy( attached.getFile(), attached, deploymentRepository, getLocalRepository(), getRetryFailedDeploymentCount() );
387 }
388 catch ( ArtifactDeploymentException e )
389 {
390 throw new MojoExecutionException( "Error deploying attached artifact " + attached.getFile() + ": "
391 + e.getMessage(), e );
392 }
393 }
394
395 }
396
397
398
399
400
401
402
403
404 private File getLocalRepoFile( Artifact artifact )
405 {
406 String path = getLocalRepository().pathOf( artifact );
407 return new File( getLocalRepository().getBasedir(), path );
408 }
409
410
411
412
413
414
415 private void processModel( Model model )
416 {
417 Parent parent = model.getParent();
418
419 if ( this.groupId == null )
420 {
421 this.groupId = model.getGroupId();
422 if ( this.groupId == null && parent != null )
423 {
424 this.groupId = parent.getGroupId();
425 }
426 }
427 if ( this.artifactId == null )
428 {
429 this.artifactId = model.getArtifactId();
430 }
431 if ( this.version == null )
432 {
433 this.version = model.getVersion();
434 if ( this.version == null && parent != null )
435 {
436 this.version = parent.getVersion();
437 }
438 }
439 if ( this.packaging == null )
440 {
441 this.packaging = model.getPackaging();
442 }
443 }
444
445
446
447
448
449
450
451
452 Model readModel( File pomFile )
453 throws MojoExecutionException
454 {
455 Reader reader = null;
456 try
457 {
458 reader = ReaderFactory.newXmlReader( pomFile );
459 return new MavenXpp3Reader().read( reader );
460 }
461 catch ( FileNotFoundException e )
462 {
463 throw new MojoExecutionException( "POM not found " + pomFile, e );
464 }
465 catch ( IOException e )
466 {
467 throw new MojoExecutionException( "Error reading POM " + pomFile, e );
468 }
469 catch ( XmlPullParserException e )
470 {
471 throw new MojoExecutionException( "Error parsing POM " + pomFile, e );
472 }
473 finally
474 {
475 IOUtil.close( reader );
476 }
477 }
478
479
480
481
482
483
484
485 private File generatePomFile()
486 throws MojoExecutionException
487 {
488 Model model = generateModel();
489
490 Writer fw = null;
491 try
492 {
493 File tempFile = File.createTempFile( "mvndeploy", ".pom" );
494 tempFile.deleteOnExit();
495
496 fw = WriterFactory.newXmlWriter( tempFile );
497 new MavenXpp3Writer().write( fw, model );
498
499 return tempFile;
500 }
501 catch ( IOException e )
502 {
503 throw new MojoExecutionException( "Error writing temporary pom file: " + e.getMessage(), e );
504 }
505 finally
506 {
507 IOUtil.close( fw );
508 }
509 }
510
511
512
513
514
515
516 private void validateArtifactInformation()
517 throws MojoExecutionException
518 {
519 Model model = generateModel();
520
521 ModelValidationResult result = modelValidator.validate( model );
522
523 if ( result.getMessageCount() > 0 )
524 {
525 throw new MojoExecutionException( "The artifact information is incomplete or not valid:\n"
526 + result.render( " " ) );
527 }
528 }
529
530
531
532
533
534
535 private Model generateModel()
536 {
537 Model model = new Model();
538
539 model.setModelVersion( "4.0.0" );
540
541 model.setGroupId( groupId );
542 model.setArtifactId( artifactId );
543 model.setVersion( version );
544 model.setPackaging( packaging );
545
546 model.setDescription( description );
547
548 return model;
549 }
550
551 void setGroupId( String groupId )
552 {
553 this.groupId = groupId;
554 }
555
556 void setArtifactId( String artifactId )
557 {
558 this.artifactId = artifactId;
559 }
560
561 void setVersion( String version )
562 {
563 this.version = version;
564 }
565
566 void setPackaging( String packaging )
567 {
568 this.packaging = packaging;
569 }
570
571 void setPomFile( File pomFile )
572 {
573 this.pomFile = pomFile;
574 }
575
576 String getGroupId()
577 {
578 return groupId;
579 }
580
581 String getArtifactId()
582 {
583 return artifactId;
584 }
585
586 String getVersion()
587 {
588 return version;
589 }
590
591 String getPackaging()
592 {
593 return packaging;
594 }
595
596 File getFile()
597 {
598 return file;
599 }
600
601 String getClassifier()
602 {
603 return classifier;
604 }
605
606 void setClassifier( String classifier )
607 {
608 this.classifier = classifier;
609 }
610 }