1 package org.apache.maven.shared.release.phase;
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.IOException;
24 import java.io.StringReader;
25 import java.io.StringWriter;
26 import java.io.Writer;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35
36 import org.apache.maven.artifact.Artifact;
37 import org.apache.maven.artifact.ArtifactUtils;
38 import org.apache.maven.model.Model;
39 import org.apache.maven.model.Scm;
40 import org.apache.maven.project.MavenProject;
41 import org.apache.maven.scm.ScmException;
42 import org.apache.maven.scm.ScmFileSet;
43 import org.apache.maven.scm.command.edit.EditScmResult;
44 import org.apache.maven.scm.manager.NoSuchScmProviderException;
45 import org.apache.maven.scm.provider.ScmProvider;
46 import org.apache.maven.scm.repository.ScmRepository;
47 import org.apache.maven.scm.repository.ScmRepositoryException;
48 import org.apache.maven.shared.release.ReleaseExecutionException;
49 import org.apache.maven.shared.release.ReleaseFailureException;
50 import org.apache.maven.shared.release.ReleaseResult;
51 import org.apache.maven.shared.release.config.ReleaseDescriptor;
52 import org.apache.maven.shared.release.env.ReleaseEnvironment;
53 import org.apache.maven.shared.release.scm.IdentifiedScm;
54 import org.apache.maven.shared.release.scm.ReleaseScmCommandException;
55 import org.apache.maven.shared.release.scm.ReleaseScmRepositoryException;
56 import org.apache.maven.shared.release.scm.ScmRepositoryConfigurator;
57 import org.apache.maven.shared.release.scm.ScmTranslator;
58 import org.apache.maven.shared.release.util.ReleaseUtil;
59 import org.codehaus.plexus.util.IOUtil;
60 import org.codehaus.plexus.util.StringUtils;
61 import org.codehaus.plexus.util.WriterFactory;
62 import org.jdom.CDATA;
63 import org.jdom.Comment;
64 import org.jdom.Document;
65 import org.jdom.Element;
66 import org.jdom.JDOMException;
67 import org.jdom.Namespace;
68 import org.jdom.Text;
69 import org.jdom.filter.ContentFilter;
70 import org.jdom.filter.ElementFilter;
71 import org.jdom.input.SAXBuilder;
72 import org.jdom.output.Format;
73 import org.jdom.output.XMLOutputter;
74
75
76
77
78
79
80 public abstract class AbstractRewritePomsPhase
81 extends AbstractReleasePhase
82 {
83
84
85
86 private ScmRepositoryConfigurator scmRepositoryConfigurator;
87
88
89
90
91 private Map<String, ScmTranslator> scmTranslators;
92
93 protected final Map<String, ScmTranslator> getScmTranslators()
94 {
95 return scmTranslators;
96 }
97
98
99
100
101 private String pomSuffix;
102
103 private String ls = ReleaseUtil.LS;
104
105 public void setLs( String ls )
106 {
107 this.ls = ls;
108 }
109
110 public ReleaseResult execute( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
111 List<MavenProject> reactorProjects )
112 throws ReleaseExecutionException, ReleaseFailureException
113 {
114 ReleaseResult result = new ReleaseResult();
115
116 transform( releaseDescriptor, releaseEnvironment, reactorProjects, false, result );
117
118 result.setResultCode( ReleaseResult.SUCCESS );
119
120 return result;
121 }
122
123 private void transform( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
124 List<MavenProject> reactorProjects, boolean simulate, ReleaseResult result )
125 throws ReleaseExecutionException, ReleaseFailureException
126 {
127 for ( MavenProject project : reactorProjects )
128 {
129 logInfo( result, "Transforming '" + project.getName() + "'..." );
130
131 transformProject( project, releaseDescriptor, releaseEnvironment, reactorProjects, simulate, result );
132 }
133 }
134
135 private void transformProject( MavenProject project, ReleaseDescriptor releaseDescriptor,
136 ReleaseEnvironment releaseEnvironment, List<MavenProject> reactorProjects,
137 boolean simulate, ReleaseResult result )
138 throws ReleaseExecutionException, ReleaseFailureException
139 {
140 Document document;
141 String intro = null;
142 String outtro = null;
143 try
144 {
145 String content = ReleaseUtil.readXmlFile( ReleaseUtil.getStandardPom( project ), ls );
146
147 content = content.replaceAll( "<([^!][^>]*?)\\s{2,}([^>]*?)>", "<$1 $2>" );
148 content = content.replaceAll( "(\\s{2,}|[^\\s])/>", "$1 />" );
149
150 SAXBuilder builder = new SAXBuilder();
151 document = builder.build( new StringReader( content ) );
152
153
154
155 normaliseLineEndings( document );
156
157
158 StringWriter w = new StringWriter();
159 Format format = Format.getRawFormat();
160 format.setLineSeparator( ls );
161 XMLOutputter out = new XMLOutputter( format );
162 out.output( document.getRootElement(), w );
163
164 int index = content.indexOf( w.toString() );
165 if ( index >= 0 )
166 {
167 intro = content.substring( 0, index );
168 outtro = content.substring( index + w.toString().length() );
169 }
170 else
171 {
172
173
174
175
176
177 final String SPACE = "\\s++";
178 final String XML = "<\\?(?:(?:[^\"'>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+>";
179 final String INTSUB = "\\[(?:(?:[^\"'\\]]++)|(?:\"[^\"]*+\")|(?:'[^\']*+'))*+\\]";
180 final String DOCTYPE =
181 "<!DOCTYPE(?:(?:[^\"'\\[>]++)|(?:\"[^\"]*+\")|(?:'[^\']*+')|(?:" + INTSUB + "))*+>";
182 final String PI = XML;
183 final String COMMENT = "<!--(?:[^-]|(?:-[^-]))*+-->";
184
185 final String INTRO =
186 "(?:(?:" + SPACE + ")|(?:" + XML + ")|(?:" + DOCTYPE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
187 final String OUTRO = "(?:(?:" + SPACE + ")|(?:" + COMMENT + ")|(?:" + PI + "))*";
188 final String POM = "(?s)(" + INTRO + ")(.*?)(" + OUTRO + ")";
189
190 Matcher matcher = Pattern.compile( POM ).matcher( content );
191 if ( matcher.matches() )
192 {
193 intro = matcher.group( 1 );
194 outtro = matcher.group( matcher.groupCount() );
195 }
196 }
197 }
198 catch ( JDOMException e )
199 {
200 throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
201 }
202 catch ( IOException e )
203 {
204 throw new ReleaseExecutionException( "Error reading POM: " + e.getMessage(), e );
205 }
206
207 ScmRepository scmRepository = null;
208 ScmProvider provider = null;
209
210 if ( isUpdateScm() )
211 {
212 try
213 {
214 scmRepository = scmRepositoryConfigurator.getConfiguredRepository( releaseDescriptor,
215 releaseEnvironment.getSettings() );
216
217 provider = scmRepositoryConfigurator.getRepositoryProvider( scmRepository );
218 }
219 catch ( ScmRepositoryException e )
220 {
221 throw new ReleaseScmRepositoryException( e.getMessage(), e.getValidationMessages() );
222 }
223 catch ( NoSuchScmProviderException e )
224 {
225 throw new ReleaseExecutionException( "Unable to configure SCM repository: " + e.getMessage(), e );
226 }
227 }
228
229 transformDocument( project, document.getRootElement(), releaseDescriptor, reactorProjects, scmRepository,
230 result, simulate );
231
232 File pomFile = ReleaseUtil.getStandardPom( project );
233
234 if ( simulate )
235 {
236 File outputFile = new File( pomFile.getParentFile(), pomFile.getName() + "." + pomSuffix );
237 writePom( outputFile, document, releaseDescriptor, project.getModelVersion(), intro, outtro );
238 }
239 else
240 {
241 writePom( pomFile, document, releaseDescriptor, project.getModelVersion(), intro, outtro, scmRepository,
242 provider );
243 }
244 }
245
246 private void normaliseLineEndings( Document document )
247 {
248 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.COMMENT ) ); i.hasNext(); )
249 {
250 Comment c = (Comment) i.next();
251 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
252 }
253 for ( Iterator<?> i = document.getDescendants( new ContentFilter( ContentFilter.CDATA ) ); i.hasNext(); )
254 {
255 CDATA c = (CDATA) i.next();
256 c.setText( ReleaseUtil.normalizeLineEndings( c.getText(), ls ) );
257 }
258 }
259
260 private void transformDocument( MavenProject project, Element rootElement, ReleaseDescriptor releaseDescriptor,
261 List<MavenProject> reactorProjects, ScmRepository scmRepository, ReleaseResult result,
262 boolean simulate )
263 throws ReleaseExecutionException, ReleaseFailureException
264 {
265 Namespace namespace = rootElement.getNamespace();
266 Map<String, String> mappedVersions = getNextVersionMap( releaseDescriptor );
267 Map<String, String> originalVersions = getOriginalVersionMap( releaseDescriptor, reactorProjects, simulate );
268 @SuppressWarnings( "unchecked" )
269 Map<String, Map<String, String>> resolvedSnapshotDependencies =
270 releaseDescriptor.getResolvedSnapshotDependencies();
271 Model model = project.getModel();
272 Element properties = rootElement.getChild( "properties", namespace );
273
274 String parentVersion = rewriteParent( project, rootElement, namespace, mappedVersions,
275 resolvedSnapshotDependencies, originalVersions );
276
277 String projectId = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
278
279 rewriteVersion( rootElement, namespace, mappedVersions, projectId, project, parentVersion );
280
281 List<Element> roots = new ArrayList<Element>();
282 roots.add( rootElement );
283 roots.addAll( getChildren( rootElement, "profiles", "profile" ) );
284
285 for ( Element root : roots )
286 {
287 rewriteArtifactVersions( getChildren( root, "dependencies", "dependency" ), mappedVersions,
288 resolvedSnapshotDependencies, originalVersions, model, properties, result,
289 releaseDescriptor );
290
291 rewriteArtifactVersions( getChildren( root, "dependencyManagement", "dependencies", "dependency" ),
292 mappedVersions, resolvedSnapshotDependencies, originalVersions, model, properties,
293 result, releaseDescriptor );
294
295 rewriteArtifactVersions( getChildren( root, "build", "extensions", "extension" ), mappedVersions,
296 resolvedSnapshotDependencies, originalVersions, model, properties, result,
297 releaseDescriptor );
298
299 List<Element> pluginElements = new ArrayList<Element>();
300 pluginElements.addAll( getChildren( root, "build", "plugins", "plugin" ) );
301 pluginElements.addAll( getChildren( root, "build", "pluginManagement", "plugins", "plugin" ) );
302
303 rewriteArtifactVersions( pluginElements, mappedVersions, resolvedSnapshotDependencies, originalVersions,
304 model, properties, result, releaseDescriptor );
305
306 for ( Element pluginElement : pluginElements )
307 {
308 rewriteArtifactVersions( getChildren( pluginElement, "dependencies", "dependency" ), mappedVersions,
309 resolvedSnapshotDependencies, originalVersions, model, properties, result,
310 releaseDescriptor );
311 }
312
313 rewriteArtifactVersions( getChildren( root, "reporting", "plugins", "plugin" ), mappedVersions,
314 resolvedSnapshotDependencies, originalVersions, model, properties, result,
315 releaseDescriptor );
316 }
317
318 String commonBasedir;
319 try
320 {
321 commonBasedir = ReleaseUtil.getCommonBasedir( reactorProjects );
322 }
323 catch ( IOException e )
324 {
325 throw new ReleaseExecutionException( "Exception occurred while calculating common basedir: "
326 + e.getMessage(), e );
327 }
328 transformScm( project, rootElement, namespace, releaseDescriptor, projectId, scmRepository, result,
329 commonBasedir );
330 }
331
332 @SuppressWarnings( "unchecked" )
333 private List<Element> getChildren( Element root, String... names )
334 {
335 Element parent = root;
336 for ( int i = 0; i < names.length - 1 && parent != null; i++ )
337 {
338 parent = parent.getChild( names[i], parent.getNamespace() );
339 }
340 if ( parent == null )
341 {
342 return Collections.emptyList();
343 }
344 return parent.getChildren( names[names.length - 1], parent.getNamespace() );
345 }
346
347
348
349
350
351
352
353
354 private void rewriteValue( Element element, String value )
355 {
356 Text text = null;
357 if ( element.getContent() != null )
358 {
359 for ( Iterator<?> it = element.getContent().iterator(); it.hasNext(); )
360 {
361 Object content = it.next();
362 if ( ( content instanceof Text ) && ( (Text) content ).getTextTrim().length() > 0 )
363 {
364 text = (Text) content;
365 while ( it.hasNext() )
366 {
367 content = it.next();
368 if ( content instanceof Text )
369 {
370 text.append( (Text) content );
371 it.remove();
372 }
373 else
374 {
375 break;
376 }
377 }
378 break;
379 }
380 }
381 }
382 if ( text == null )
383 {
384 element.addContent( value );
385 }
386 else
387 {
388 String chars = text.getText();
389 String trimmed = text.getTextTrim();
390 int idx = chars.indexOf( trimmed );
391 String leadingWhitespace = chars.substring( 0, idx );
392 String trailingWhitespace = chars.substring( idx + trimmed.length() );
393 text.setText( leadingWhitespace + value + trailingWhitespace );
394 }
395 }
396
397 private void rewriteVersion( Element rootElement, Namespace namespace, Map<String, String> mappedVersions, String projectId,
398 MavenProject project, String parentVersion )
399 throws ReleaseFailureException
400 {
401 Element versionElement = rootElement.getChild( "version", namespace );
402 String version = mappedVersions.get( projectId );
403 if ( version == null )
404 {
405 throw new ReleaseFailureException( "Version for '" + project.getName() + "' was not mapped" );
406 }
407
408 if ( versionElement == null )
409 {
410 if ( !version.equals( parentVersion ) )
411 {
412
413 Element artifactIdElement = rootElement.getChild( "artifactId", namespace );
414 int index = rootElement.indexOf( artifactIdElement );
415
416 versionElement = new Element( "version", namespace );
417 versionElement.setText( version );
418 rootElement.addContent( index + 1, new Text( "\n " ) );
419 rootElement.addContent( index + 2, versionElement );
420 }
421 }
422 else
423 {
424 rewriteValue( versionElement, version );
425 }
426 }
427
428 private String rewriteParent( MavenProject project, Element rootElement, Namespace namespace, Map<String, String> mappedVersions,
429 Map<String, Map<String, String>> resolvedSnapshotDependencies, Map<String, String> originalVersions )
430 throws ReleaseFailureException
431 {
432 String parentVersion = null;
433 if ( project.hasParent() )
434 {
435 Element parentElement = rootElement.getChild( "parent", namespace );
436 Element versionElement = parentElement.getChild( "version", namespace );
437 MavenProject parent = project.getParent();
438 String key = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
439 parentVersion = mappedVersions.get( key );
440 if ( parentVersion == null )
441 {
442
443 parentVersion = getResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
444 }
445 if ( parentVersion == null )
446 {
447 if ( parent.getVersion().equals( originalVersions.get( key ) ) )
448 {
449 throw new ReleaseFailureException( "Version for parent '" + parent.getName() + "' was not mapped" );
450 }
451 }
452 else
453 {
454 rewriteValue( versionElement, parentVersion );
455 }
456 }
457 return parentVersion;
458 }
459
460 private void rewriteArtifactVersions( Collection<Element> elements, Map<String, String> mappedVersions,
461 Map<String, Map<String, String>> resolvedSnapshotDependencies, Map<String, String> originalVersions,
462 Model projectModel, Element properties, ReleaseResult result,
463 ReleaseDescriptor releaseDescriptor )
464 throws ReleaseExecutionException, ReleaseFailureException
465 {
466 if ( elements == null )
467 {
468 return;
469 }
470 String projectId = ArtifactUtils.versionlessKey( projectModel.getGroupId(), projectModel.getArtifactId() );
471 for ( Element element : elements )
472 {
473 Element versionElement = element.getChild( "version", element.getNamespace() );
474 if ( versionElement == null )
475 {
476
477 continue;
478 }
479 String rawVersion = versionElement.getTextTrim();
480
481 Element groupIdElement = element.getChild( "groupId", element.getNamespace() );
482 if ( groupIdElement == null )
483 {
484 if ( "plugin".equals( element.getName() ) )
485 {
486 groupIdElement = new Element( "groupId", element.getNamespace() );
487 groupIdElement.setText( "org.apache.maven.plugins" );
488 }
489 else
490 {
491
492 continue;
493 }
494 }
495 String groupId = ReleaseUtil.interpolate( groupIdElement.getTextTrim(), projectModel );
496
497 Element artifactIdElement = element.getChild( "artifactId", element.getNamespace() );
498 if ( artifactIdElement == null )
499 {
500
501 continue;
502 }
503 String artifactId = ReleaseUtil.interpolate( artifactIdElement.getTextTrim(), projectModel );
504
505 String key = ArtifactUtils.versionlessKey( groupId, artifactId );
506 String resolvedSnapshotVersion = getResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
507 String mappedVersion = mappedVersions.get( key );
508 String originalVersion = originalVersions.get( key );
509 if ( originalVersion == null )
510 {
511 originalVersion = getOriginalResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
512 }
513
514
515 if ( mappedVersion != null && mappedVersion.endsWith( Artifact.SNAPSHOT_VERSION )
516 && !rawVersion.endsWith( Artifact.SNAPSHOT_VERSION ) && !releaseDescriptor.isUpdateDependencies() )
517 {
518 continue;
519 }
520
521 if ( mappedVersion != null )
522 {
523 if ( rawVersion.equals( originalVersion ) )
524 {
525 logInfo( result, " Updating " + artifactId + " to " + mappedVersion );
526 rewriteValue( versionElement, mappedVersion );
527 }
528 else if ( rawVersion.matches( "\\$\\{.+\\}" ) )
529 {
530 String expression = rawVersion.substring( 2, rawVersion.length() - 1 );
531
532 if ( expression.startsWith( "project." ) || expression.startsWith( "pom." )
533 || "version".equals( expression ) )
534 {
535 if ( !mappedVersion.equals( mappedVersions.get( projectId ) ) )
536 {
537 logInfo( result, " Updating " + artifactId + " to " + mappedVersion );
538 rewriteValue( versionElement, mappedVersion );
539 }
540 else
541 {
542 logInfo( result, " Ignoring artifact version update for expression " + rawVersion );
543 }
544 }
545 else if ( properties != null )
546 {
547
548 Element property = properties.getChild( expression, properties.getNamespace() );
549 if ( property != null )
550 {
551 String propertyValue = property.getTextTrim();
552
553 if ( propertyValue.equals( originalVersion ) )
554 {
555 logInfo( result, " Updating " + rawVersion + " to " + mappedVersion );
556
557 rewriteValue( property, mappedVersion );
558 }
559 else if ( mappedVersion.equals( propertyValue ) )
560 {
561
562 logInfo( result, " Ignoring artifact version update for expression " + rawVersion
563 + " because it is already updated" );
564 }
565 else if ( !mappedVersion.equals( rawVersion ) )
566 {
567 if ( mappedVersion.matches( "\\$\\{project.+\\}" )
568 || mappedVersion.matches( "\\$\\{pom.+\\}" ) || "${version}".equals( mappedVersion ) )
569 {
570 logInfo( result, " Ignoring artifact version update for expression "
571 + mappedVersion );
572
573 }
574 else
575 {
576
577 throw new ReleaseFailureException( "The artifact (" + key + ") requires a "
578 + "different version (" + mappedVersion + ") than what is found ("
579 + propertyValue + ") for the expression (" + expression + ") in the "
580 + "project (" + projectId + ")." );
581 }
582 }
583 }
584 else
585 {
586
587
588 throw new ReleaseFailureException( "The version could not be updated: " + rawVersion );
589 }
590 }
591 }
592 else
593 {
594
595 }
596 }
597 else if ( resolvedSnapshotVersion != null )
598 {
599 logInfo( result, " Updating " + artifactId + " to " + resolvedSnapshotVersion );
600
601 rewriteValue( versionElement, resolvedSnapshotVersion );
602 }
603 else
604 {
605
606 }
607 }
608 }
609
610 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
611 String intro, String outtro, ScmRepository repository, ScmProvider provider )
612 throws ReleaseExecutionException, ReleaseScmCommandException
613 {
614 try
615 {
616 if ( isUpdateScm() && ( releaseDescriptor.isScmUseEditMode() || provider.requiresEditMode() ) )
617 {
618 EditScmResult result = provider.edit( repository, new ScmFileSet(
619 new File( releaseDescriptor.getWorkingDirectory() ), pomFile ) );
620
621 if ( !result.isSuccess() )
622 {
623 throw new ReleaseScmCommandException( "Unable to enable editing on the POM", result );
624 }
625 }
626 }
627 catch ( ScmException e )
628 {
629 throw new ReleaseExecutionException( "An error occurred enabling edit mode: " + e.getMessage(), e );
630 }
631
632 writePom( pomFile, document, releaseDescriptor, modelVersion, intro, outtro );
633 }
634
635 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
636 String intro, String outtro )
637 throws ReleaseExecutionException
638 {
639 Element rootElement = document.getRootElement();
640
641 if ( releaseDescriptor.isAddSchema() )
642 {
643 Namespace pomNamespace = Namespace.getNamespace( "", "http://maven.apache.org/POM/" + modelVersion );
644 rootElement.setNamespace( pomNamespace );
645 Namespace xsiNamespace = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
646 rootElement.addNamespaceDeclaration( xsiNamespace );
647
648 if ( rootElement.getAttribute( "schemaLocation", xsiNamespace ) == null )
649 {
650 rootElement.setAttribute( "schemaLocation", "http://maven.apache.org/POM/" + modelVersion
651 + " http://maven.apache.org/maven-v" + modelVersion.replace( '.', '_' ) + ".xsd", xsiNamespace );
652 }
653
654
655 ElementFilter elementFilter = new ElementFilter( Namespace.getNamespace( "" ) );
656 for ( Iterator<?> i = rootElement.getDescendants( elementFilter ); i.hasNext(); )
657 {
658 Element e = (Element) i.next();
659 e.setNamespace( pomNamespace );
660 }
661 }
662
663 Writer writer = null;
664 try
665 {
666 writer = WriterFactory.newXmlWriter( pomFile );
667
668 if ( intro != null )
669 {
670 writer.write( intro );
671 }
672
673 Format format = Format.getRawFormat();
674 format.setLineSeparator( ls );
675 XMLOutputter out = new XMLOutputter( format );
676 out.output( document.getRootElement(), writer );
677
678 if ( outtro != null )
679 {
680 writer.write( outtro );
681 }
682 }
683 catch ( IOException e )
684 {
685 throw new ReleaseExecutionException( "Error writing POM: " + e.getMessage(), e );
686 }
687 finally
688 {
689 IOUtil.close( writer );
690 }
691 }
692
693 public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
694 List<MavenProject> reactorProjects )
695 throws ReleaseExecutionException, ReleaseFailureException
696 {
697 ReleaseResult result = new ReleaseResult();
698
699 transform( releaseDescriptor, releaseEnvironment, reactorProjects, true, result );
700
701 result.setResultCode( ReleaseResult.SUCCESS );
702
703 return result;
704 }
705
706 public ReleaseResult clean( List<MavenProject> reactorProjects )
707 {
708 ReleaseResult result = new ReleaseResult();
709
710 super.clean( reactorProjects );
711
712 if ( reactorProjects != null )
713 {
714 for ( MavenProject project : reactorProjects )
715 {
716 File pomFile = ReleaseUtil.getStandardPom( project );
717
718 if ( pomFile != null )
719 {
720 File file = new File( pomFile.getParentFile(), pomFile.getName() + "." + pomSuffix );
721 if ( file.exists() )
722 {
723 file.delete();
724 }
725 }
726 }
727 }
728
729 result.setResultCode( ReleaseResult.SUCCESS );
730
731 return result;
732 }
733
734 protected abstract String getResolvedSnapshotVersion( String artifactVersionlessKey,
735 Map<String, Map<String, String>> resolvedSnapshots );
736
737 protected abstract Map<String, String> getOriginalVersionMap( ReleaseDescriptor releaseDescriptor,
738 List<MavenProject> reactorProjects, boolean simulate );
739
740 protected abstract Map<String,String> getNextVersionMap( ReleaseDescriptor releaseDescriptor );
741
742 protected abstract void transformScm( MavenProject project, Element rootElement, Namespace namespace,
743 ReleaseDescriptor releaseDescriptor, String projectId,
744 ScmRepository scmRepository, ReleaseResult result, String commonBasedir )
745 throws ReleaseExecutionException;
746
747
748
749
750
751
752 protected boolean isUpdateScm()
753 {
754 return true;
755 }
756
757 protected String getOriginalResolvedSnapshotVersion( String artifactVersionlessKey,
758 Map<String, Map<String, String>> resolvedSnapshots )
759 {
760 Map<String, String> versionsMap = resolvedSnapshots.get( artifactVersionlessKey );
761
762 if ( versionsMap != null )
763 {
764 return versionsMap.get( ReleaseDescriptor.ORIGINAL_VERSION );
765 }
766 else
767 {
768 return null;
769 }
770 }
771
772 protected Element rewriteElement( String name, String value, Element root, Namespace namespace )
773 {
774 Element tagElement = root.getChild( name, namespace );
775 if ( tagElement != null )
776 {
777 if ( value != null )
778 {
779 rewriteValue( tagElement, value );
780 }
781 else
782 {
783 int index = root.indexOf( tagElement );
784 root.removeContent( index );
785 for ( int i = index - 1; i >= 0; i-- )
786 {
787 if ( root.getContent( i ) instanceof Text )
788 {
789 root.removeContent( i );
790 }
791 else
792 {
793 break;
794 }
795 }
796 }
797 }
798 else
799 {
800 if ( value != null )
801 {
802 Element element = new Element( name, namespace );
803 element.setText( value );
804 root.addContent( " " ).addContent( element ).addContent( "\n " );
805 tagElement = element;
806 }
807 }
808 return tagElement;
809 }
810
811 protected Scm buildScm( MavenProject project )
812 {
813 IdentifiedScm scm;
814 if ( project.getOriginalModel().getScm() == null )
815 {
816 scm = null;
817 }
818 else
819 {
820 scm = new IdentifiedScm();
821 scm.setConnection( project.getOriginalModel().getScm().getConnection() );
822 scm.setDeveloperConnection( project.getOriginalModel().getScm().getDeveloperConnection() );
823 scm.setTag( project.getOriginalModel().getScm().getTag() );
824 scm.setUrl( project.getOriginalModel().getScm().getUrl() );
825 scm.setId( project.getProperties().getProperty( "project.scm.id" ) );
826 }
827 return scm;
828 }
829
830
831
832
833
834
835
836
837
838
839 protected static String translateUrlPath( String trunkPath, String tagPath, String urlPath )
840 {
841 trunkPath = trunkPath.trim();
842 tagPath = tagPath.trim();
843
844 if ( trunkPath.endsWith( "/" ) )
845 {
846 trunkPath = trunkPath.substring( 0, trunkPath.length() - 1 );
847 }
848 if ( tagPath.endsWith( "/" ) )
849 {
850 tagPath = tagPath.substring( 0, tagPath.length() - 1 );
851 }
852 char[] tagPathChars = trunkPath.toCharArray();
853 char[] trunkPathChars = tagPath.toCharArray();
854
855 int i = 0;
856 while ( ( i < tagPathChars.length ) && ( i < trunkPathChars.length ) && tagPathChars[i] == trunkPathChars[i] )
857 {
858 ++i;
859 }
860
861
862 if ( i == 0 || urlPath.indexOf( trunkPath.substring( i ) ) < 0 )
863 {
864 return tagPath;
865 }
866 else
867 {
868 return StringUtils.replace( urlPath, trunkPath.substring( i ), tagPath.substring( i ) );
869 }
870 }
871 }