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 = releaseDescriptor.getResolvedSnapshotDependencies();
270 Model model = project.getModel();
271 Element properties = rootElement.getChild( "properties", namespace );
272
273 String parentVersion = rewriteParent( project, rootElement, namespace, mappedVersions,
274 resolvedSnapshotDependencies, originalVersions );
275
276 String projectId = ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
277
278 rewriteVersion( rootElement, namespace, mappedVersions, projectId, project, parentVersion );
279
280 List<Element> roots = new ArrayList<Element>();
281 roots.add( rootElement );
282 roots.addAll( getChildren( rootElement, "profiles", "profile" ) );
283
284 for ( Element root : roots )
285 {
286 rewriteArtifactVersions( getChildren( root, "dependencies", "dependency" ), mappedVersions,
287 resolvedSnapshotDependencies, originalVersions, model, properties, result,
288 releaseDescriptor );
289
290 rewriteArtifactVersions( getChildren( root, "dependencyManagement", "dependencies", "dependency" ),
291 mappedVersions, resolvedSnapshotDependencies, originalVersions, model, properties,
292 result, releaseDescriptor );
293
294 rewriteArtifactVersions( getChildren( root, "build", "extensions", "extension" ), mappedVersions,
295 resolvedSnapshotDependencies, originalVersions, model, properties, result,
296 releaseDescriptor );
297
298 List<Element> pluginElements = new ArrayList<Element>();
299 pluginElements.addAll( getChildren( root, "build", "plugins", "plugin" ) );
300 pluginElements.addAll( getChildren( root, "build", "pluginManagement", "plugins", "plugin" ) );
301
302 rewriteArtifactVersions( pluginElements, mappedVersions, resolvedSnapshotDependencies, originalVersions,
303 model, properties, result, releaseDescriptor );
304
305 for ( Element pluginElement : pluginElements )
306 {
307 rewriteArtifactVersions( getChildren( pluginElement, "dependencies", "dependency" ), mappedVersions,
308 resolvedSnapshotDependencies, originalVersions, model, properties, result,
309 releaseDescriptor );
310 }
311
312 rewriteArtifactVersions( getChildren( root, "reporting", "plugins", "plugin" ), mappedVersions,
313 resolvedSnapshotDependencies, originalVersions, model, properties, result,
314 releaseDescriptor );
315 }
316
317 String commonBasedir;
318 try
319 {
320 commonBasedir = ReleaseUtil.getCommonBasedir( reactorProjects );
321 }
322 catch ( IOException e )
323 {
324 throw new ReleaseExecutionException( "Exception occurred while calculating common basedir: "
325 + e.getMessage(), e );
326 }
327 transformScm( project, rootElement, namespace, releaseDescriptor, projectId, scmRepository, result,
328 commonBasedir );
329 }
330
331 @SuppressWarnings( "unchecked" )
332 private List<Element> getChildren( Element root, String... names )
333 {
334 Element parent = root;
335 for ( int i = 0; i < names.length - 1 && parent != null; i++ )
336 {
337 parent = parent.getChild( names[i], parent.getNamespace() );
338 }
339 if ( parent == null )
340 {
341 return Collections.emptyList();
342 }
343 return parent.getChildren( names[names.length - 1], parent.getNamespace() );
344 }
345
346
347
348
349
350
351
352
353 private void rewriteValue( Element element, String value )
354 {
355 Text text = null;
356 if ( element.getContent() != null )
357 {
358 for ( Iterator<?> it = element.getContent().iterator(); it.hasNext(); )
359 {
360 Object content = it.next();
361 if ( ( content instanceof Text ) && ( (Text) content ).getTextTrim().length() > 0 )
362 {
363 text = (Text) content;
364 while ( it.hasNext() )
365 {
366 content = it.next();
367 if ( content instanceof Text )
368 {
369 text.append( (Text) content );
370 it.remove();
371 }
372 else
373 {
374 break;
375 }
376 }
377 break;
378 }
379 }
380 }
381 if ( text == null )
382 {
383 element.addContent( value );
384 }
385 else
386 {
387 String chars = text.getText();
388 String trimmed = text.getTextTrim();
389 int idx = chars.indexOf( trimmed );
390 String leadingWhitespace = chars.substring( 0, idx );
391 String trailingWhitespace = chars.substring( idx + trimmed.length() );
392 text.setText( leadingWhitespace + value + trailingWhitespace );
393 }
394 }
395
396 private void rewriteVersion( Element rootElement, Namespace namespace, Map<String, String> mappedVersions, String projectId,
397 MavenProject project, String parentVersion )
398 throws ReleaseFailureException
399 {
400 Element versionElement = rootElement.getChild( "version", namespace );
401 String version = mappedVersions.get( projectId );
402 if ( version == null )
403 {
404 throw new ReleaseFailureException( "Version for '" + project.getName() + "' was not mapped" );
405 }
406
407 if ( versionElement == null )
408 {
409 if ( !version.equals( parentVersion ) )
410 {
411
412 Element artifactIdElement = rootElement.getChild( "artifactId", namespace );
413 int index = rootElement.indexOf( artifactIdElement );
414
415 versionElement = new Element( "version", namespace );
416 versionElement.setText( version );
417 rootElement.addContent( index + 1, new Text( "\n " ) );
418 rootElement.addContent( index + 2, versionElement );
419 }
420 }
421 else
422 {
423 rewriteValue( versionElement, version );
424 }
425 }
426
427 private String rewriteParent( MavenProject project, Element rootElement, Namespace namespace, Map<String, String> mappedVersions,
428 Map<String, Map<String, String>> resolvedSnapshotDependencies, Map<String, String> originalVersions )
429 throws ReleaseFailureException
430 {
431 String parentVersion = null;
432 if ( project.hasParent() )
433 {
434 Element parentElement = rootElement.getChild( "parent", namespace );
435 Element versionElement = parentElement.getChild( "version", namespace );
436 MavenProject parent = project.getParent();
437 String key = ArtifactUtils.versionlessKey( parent.getGroupId(), parent.getArtifactId() );
438 parentVersion = mappedVersions.get( key );
439 if ( parentVersion == null )
440 {
441
442 parentVersion = getResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
443 }
444 if ( parentVersion == null )
445 {
446 if ( parent.getVersion().equals( originalVersions.get( key ) ) )
447 {
448 throw new ReleaseFailureException( "Version for parent '" + parent.getName() + "' was not mapped" );
449 }
450 }
451 else
452 {
453 rewriteValue( versionElement, parentVersion );
454 }
455 }
456 return parentVersion;
457 }
458
459 private void rewriteArtifactVersions( Collection<Element> elements, Map<String, String> mappedVersions,
460 Map<String, Map<String, String>> resolvedSnapshotDependencies, Map<String, String> originalVersions,
461 Model projectModel, Element properties, ReleaseResult result,
462 ReleaseDescriptor releaseDescriptor )
463 throws ReleaseExecutionException, ReleaseFailureException
464 {
465 if ( elements == null )
466 {
467 return;
468 }
469 String projectId = ArtifactUtils.versionlessKey( projectModel.getGroupId(), projectModel.getArtifactId() );
470 for ( Element element : elements )
471 {
472 Element versionElement = element.getChild( "version", element.getNamespace() );
473 if ( versionElement == null )
474 {
475
476 continue;
477 }
478 String rawVersion = versionElement.getTextTrim();
479
480 Element groupIdElement = element.getChild( "groupId", element.getNamespace() );
481 if ( groupIdElement == null )
482 {
483 if ( "plugin".equals( element.getName() ) )
484 {
485 groupIdElement = new Element( "groupId", element.getNamespace() );
486 groupIdElement.setText( "org.apache.maven.plugins" );
487 }
488 else
489 {
490
491 continue;
492 }
493 }
494 String groupId = ReleaseUtil.interpolate( groupIdElement.getTextTrim(), projectModel );
495
496 Element artifactIdElement = element.getChild( "artifactId", element.getNamespace() );
497 if ( artifactIdElement == null )
498 {
499
500 continue;
501 }
502 String artifactId = ReleaseUtil.interpolate( artifactIdElement.getTextTrim(), projectModel);
503
504 String key = ArtifactUtils.versionlessKey( groupId, artifactId );
505 String resolvedSnapshotVersion = getResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
506 String mappedVersion = mappedVersions.get( key );
507 String originalVersion = originalVersions.get( key );
508 if ( originalVersion == null )
509 {
510 originalVersion = getOriginalResolvedSnapshotVersion( key, resolvedSnapshotDependencies );
511 }
512
513
514 if ( mappedVersion != null && mappedVersion.endsWith( Artifact.SNAPSHOT_VERSION )
515 && !rawVersion.endsWith( Artifact.SNAPSHOT_VERSION ) && !releaseDescriptor.isUpdateDependencies() )
516 {
517 continue;
518 }
519
520 if ( mappedVersion != null )
521 {
522 if ( rawVersion.equals( originalVersion ) )
523 {
524 logInfo( result, " Updating " + artifactId + " to " + mappedVersion );
525 rewriteValue( versionElement, mappedVersion );
526 }
527 else if ( rawVersion.matches( "\\$\\{.+\\}" ) )
528 {
529 String expression = rawVersion.substring( 2, rawVersion.length() - 1 );
530
531 if ( expression.startsWith( "project." ) || expression.startsWith( "pom." )
532 || "version".equals( expression ) )
533 {
534 if ( !mappedVersion.equals( mappedVersions.get( projectId ) ) )
535 {
536 logInfo( result, " Updating " + artifactId + " to " + mappedVersion );
537 rewriteValue( versionElement, mappedVersion );
538 }
539 else
540 {
541 logInfo( result, " Ignoring artifact version update for expression " + rawVersion );
542 }
543 }
544 else if ( properties != null )
545 {
546
547 Element property = properties.getChild( expression, properties.getNamespace() );
548 if ( property != null )
549 {
550 String propertyValue = property.getTextTrim();
551
552 if ( propertyValue.equals( originalVersion ) )
553 {
554 logInfo( result, " Updating " + rawVersion + " to " + mappedVersion );
555
556 rewriteValue( property, mappedVersion );
557 }
558 else if ( mappedVersion.equals( propertyValue ) )
559 {
560
561 logInfo( result, " Ignoring artifact version update for expression " + rawVersion
562 + " because it is already updated" );
563 }
564 else if ( !mappedVersion.equals( rawVersion ) )
565 {
566 if ( mappedVersion.matches( "\\$\\{project.+\\}" )
567 || mappedVersion.matches( "\\$\\{pom.+\\}" ) || "${version}".equals( mappedVersion ) )
568 {
569 logInfo( result, " Ignoring artifact version update for expression "
570 + mappedVersion );
571
572 }
573 else
574 {
575
576 throw new ReleaseFailureException( "The artifact (" + key + ") requires a "
577 + "different version (" + mappedVersion + ") than what is found ("
578 + propertyValue + ") for the expression (" + expression + ") in the "
579 + "project (" + projectId + ")." );
580 }
581 }
582 }
583 else
584 {
585
586
587 throw new ReleaseFailureException( "The version could not be updated: " + rawVersion );
588 }
589 }
590 }
591 else
592 {
593
594 }
595 }
596 else if ( resolvedSnapshotVersion != null )
597 {
598 logInfo( result, " Updating " + artifactId + " to " + resolvedSnapshotVersion );
599
600 rewriteValue( versionElement, resolvedSnapshotVersion );
601 }
602 else
603 {
604
605 }
606 }
607 }
608
609 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
610 String intro, String outtro, ScmRepository repository, ScmProvider provider )
611 throws ReleaseExecutionException, ReleaseScmCommandException
612 {
613 try
614 {
615 if ( isUpdateScm() && ( releaseDescriptor.isScmUseEditMode() || provider.requiresEditMode() ) )
616 {
617 EditScmResult result = provider.edit( repository, new ScmFileSet(
618 new File( releaseDescriptor.getWorkingDirectory() ), pomFile ) );
619
620 if ( !result.isSuccess() )
621 {
622 throw new ReleaseScmCommandException( "Unable to enable editing on the POM", result );
623 }
624 }
625 }
626 catch ( ScmException e )
627 {
628 throw new ReleaseExecutionException( "An error occurred enabling edit mode: " + e.getMessage(), e );
629 }
630
631 writePom( pomFile, document, releaseDescriptor, modelVersion, intro, outtro );
632 }
633
634 private void writePom( File pomFile, Document document, ReleaseDescriptor releaseDescriptor, String modelVersion,
635 String intro, String outtro )
636 throws ReleaseExecutionException
637 {
638 Element rootElement = document.getRootElement();
639
640 if ( releaseDescriptor.isAddSchema() )
641 {
642 Namespace pomNamespace = Namespace.getNamespace( "", "http://maven.apache.org/POM/" + modelVersion );
643 rootElement.setNamespace( pomNamespace );
644 Namespace xsiNamespace = Namespace.getNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
645 rootElement.addNamespaceDeclaration( xsiNamespace );
646
647 if ( rootElement.getAttribute( "schemaLocation", xsiNamespace ) == null )
648 {
649 rootElement.setAttribute( "schemaLocation", "http://maven.apache.org/POM/" + modelVersion
650 + " http://maven.apache.org/maven-v" + modelVersion.replace( '.', '_' ) + ".xsd", xsiNamespace );
651 }
652
653
654 ElementFilter elementFilter = new ElementFilter( Namespace.getNamespace( "" ) );
655 for ( Iterator<?> i = rootElement.getDescendants( elementFilter ); i.hasNext(); )
656 {
657 Element e = (Element) i.next();
658 e.setNamespace( pomNamespace );
659 }
660 }
661
662 Writer writer = null;
663 try
664 {
665 writer = WriterFactory.newXmlWriter( pomFile );
666
667 if ( intro != null )
668 {
669 writer.write( intro );
670 }
671
672 Format format = Format.getRawFormat();
673 format.setLineSeparator( ls );
674 XMLOutputter out = new XMLOutputter( format );
675 out.output( document.getRootElement(), writer );
676
677 if ( outtro != null )
678 {
679 writer.write( outtro );
680 }
681 }
682 catch ( IOException e )
683 {
684 throw new ReleaseExecutionException( "Error writing POM: " + e.getMessage(), e );
685 }
686 finally
687 {
688 IOUtil.close( writer );
689 }
690 }
691
692 public ReleaseResult simulate( ReleaseDescriptor releaseDescriptor, ReleaseEnvironment releaseEnvironment,
693 List<MavenProject> reactorProjects )
694 throws ReleaseExecutionException, ReleaseFailureException
695 {
696 ReleaseResult result = new ReleaseResult();
697
698 transform( releaseDescriptor, releaseEnvironment, reactorProjects, true, result );
699
700 result.setResultCode( ReleaseResult.SUCCESS );
701
702 return result;
703 }
704
705 public ReleaseResult clean( List<MavenProject> reactorProjects )
706 {
707 ReleaseResult result = new ReleaseResult();
708
709 super.clean( reactorProjects );
710
711 if ( reactorProjects != null )
712 {
713 for ( MavenProject project : reactorProjects )
714 {
715 File pomFile = ReleaseUtil.getStandardPom( project );
716
717 if ( pomFile != null )
718 {
719 File file = new File( pomFile.getParentFile(), pomFile.getName() + "." + pomSuffix );
720 if ( file.exists() )
721 {
722 file.delete();
723 }
724 }
725 }
726 }
727
728 result.setResultCode( ReleaseResult.SUCCESS );
729
730 return result;
731 }
732
733 protected abstract String getResolvedSnapshotVersion( String artifactVersionlessKey, Map<String, Map<String,String>> resolvedSnapshots );
734
735 protected abstract Map<String, String> getOriginalVersionMap( ReleaseDescriptor releaseDescriptor, List<MavenProject> reactorProjects,
736 boolean simulate );
737
738 protected abstract Map<String,String> getNextVersionMap( ReleaseDescriptor releaseDescriptor );
739
740 protected abstract void transformScm( MavenProject project, Element rootElement, Namespace namespace,
741 ReleaseDescriptor releaseDescriptor, String projectId,
742 ScmRepository scmRepository, ReleaseResult result, String commonBasedir )
743 throws ReleaseExecutionException;
744
745
746
747
748
749
750 protected boolean isUpdateScm()
751 {
752 return true;
753 }
754
755 protected String getOriginalResolvedSnapshotVersion( String artifactVersionlessKey, Map<String, Map<String, String>> resolvedSnapshots )
756 {
757 Map<String, String> versionsMap = resolvedSnapshots.get( artifactVersionlessKey );
758
759 if ( versionsMap != null )
760 {
761 return versionsMap.get( ReleaseDescriptor.ORIGINAL_VERSION );
762 }
763 else
764 {
765 return null;
766 }
767 }
768
769 protected Element rewriteElement( String name, String value, Element root, Namespace namespace )
770 {
771 Element tagElement = root.getChild( name, namespace );
772 if ( tagElement != null )
773 {
774 if ( value != null )
775 {
776 rewriteValue( tagElement, value );
777 }
778 else
779 {
780 int index = root.indexOf( tagElement );
781 root.removeContent( index );
782 for ( int i = index - 1; i >= 0; i-- )
783 {
784 if ( root.getContent( i ) instanceof Text )
785 {
786 root.removeContent( i );
787 }
788 else
789 {
790 break;
791 }
792 }
793 }
794 }
795 else
796 {
797 if ( value != null )
798 {
799 Element element = new Element( name, namespace );
800 element.setText( value );
801 root.addContent( " " ).addContent( element ).addContent( "\n " );
802 tagElement = element;
803 }
804 }
805 return tagElement;
806 }
807
808 protected Scm buildScm( MavenProject project )
809 {
810 IdentifiedScm scm;
811 if ( project.getOriginalModel().getScm() == null )
812 {
813 scm = null;
814 }
815 else
816 {
817 scm = new IdentifiedScm();
818 scm.setConnection( project.getOriginalModel().getScm().getConnection() );
819 scm.setDeveloperConnection( project.getOriginalModel().getScm().getDeveloperConnection() );
820 scm.setTag( project.getOriginalModel().getScm().getTag() );
821 scm.setUrl( project.getOriginalModel().getScm().getUrl() );
822 scm.setId( project.getProperties().getProperty( "project.scm.id" ) );
823 }
824 return scm;
825 }
826
827
828
829
830
831
832
833
834
835
836 protected static String translateUrlPath( String trunkPath, String tagPath, String urlPath )
837 {
838 trunkPath = trunkPath.trim();
839 tagPath = tagPath.trim();
840
841 if ( trunkPath.endsWith( "/" ) )
842 {
843 trunkPath = trunkPath.substring( 0, trunkPath.length() - 1 );
844 }
845 if ( tagPath.endsWith( "/" ) )
846 {
847 tagPath = tagPath.substring( 0, tagPath.length() - 1 );
848 }
849 char[] tagPathChars = trunkPath.toCharArray();
850 char[] trunkPathChars = tagPath.toCharArray();
851
852 int i = 0;
853 while ( ( i < tagPathChars.length ) && ( i < trunkPathChars.length ) && tagPathChars[i] == trunkPathChars[i] )
854 {
855 ++i;
856 }
857
858
859 if ( i == 0 || urlPath.indexOf( trunkPath.substring( i ) ) < 0 )
860 {
861 return tagPath;
862 }
863 else
864 {
865 return StringUtils.replace( urlPath, trunkPath.substring( i ), tagPath.substring( i ) );
866 }
867 }
868 }