diff --git a/src/main/java/org/codehaus/mojo/versions/SetScmTagMojo.java b/src/main/java/org/codehaus/mojo/versions/SetScmTagMojo.java index 111f762ac9..46d5cbdd0e 100644 --- a/src/main/java/org/codehaus/mojo/versions/SetScmTagMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/SetScmTagMojo.java @@ -93,7 +93,8 @@ protected void update( ModifiedPomXMLEventReader pom ) List failures = new ArrayList<>(); if ( !isBlank( newTag ) ) { - getLog().info( "Updating tag: " + scm.getTag() + " -> " + newTag ); + getLog().info( "Updating tag: " + ( scm != null && scm.getTag() != null + ? scm.getTag() : "(empty)" ) + " -> " + newTag ); if ( !PomHelper.setElementValue( pom, "/project/scm", "tag", newTag ) ) { failures.add( "tag: " + newTag ); @@ -101,7 +102,8 @@ protected void update( ModifiedPomXMLEventReader pom ) } if ( !isBlank( connection ) ) { - getLog().info( "Updating connection: " + scm.getConnection() + " -> " + connection ); + getLog().info( "Updating connection: " + ( scm != null && scm.getConnection() != null + ? scm.getConnection() : "(empty)" ) + " -> " + connection ); if ( !PomHelper.setElementValue( pom, "/project/scm", "connection", connection ) ) { failures.add( "connection: " + connection ); @@ -109,7 +111,9 @@ protected void update( ModifiedPomXMLEventReader pom ) } if ( !isBlank( developerConnection ) ) { - getLog().info( "Updating developerConnection: " + scm.getDeveloperConnection() + " -> " + getLog().info( "Updating developerConnection: " + + ( scm != null && scm.getDeveloperConnection() != null + ? scm.getDeveloperConnection() : "(empty)" ) + " -> " + developerConnection ); if ( !PomHelper.setElementValue( pom, "/project/scm", "developerConnection", developerConnection ) ) @@ -119,7 +123,8 @@ protected void update( ModifiedPomXMLEventReader pom ) } if ( !isBlank( url ) ) { - getLog().info( "Updating url: " + scm.getUrl() + " -> " + url ); + getLog().info( "Updating url: " + ( scm != null && scm.getUrl() != null + ? scm.getUrl() : "(empty)" ) + " -> " + url ); if ( !PomHelper.setElementValue( pom, "/project/scm", "url", url ) ) { failures.add( "url: " + url ); diff --git a/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java b/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java index 7ace74ab6b..b7dde0e88b 100644 --- a/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java +++ b/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java @@ -278,127 +278,112 @@ public static boolean setElementValue( ModifiedPomXMLEventReader pom, String par { class ElementValueInternal { + private final String parentName; + private final String superParentPath; + private static final int MARK_CHILD_BEGIN = 0; + private static final int MARK_OPTION = 1; + private static final int PARENT_BEGIN = 2; - } - - pom.rewind(); - int lastDelimeterIndex = parentPath.lastIndexOf( '/' ); - try - { - return setElementValueInternal( "", - parentPath.substring( lastDelimeterIndex + 1 ), - parentPath.substring( 0, lastDelimeterIndex ), - pom, parentPath, elementName, value, shouldCreate ); - } - finally - { - range( 0, 3 ).forEach( pom::clearMark ); - } - } - - /** - * Sets the value of the given element given its parent element path. - * If the element is not found in the parent element, the method will create the element. - * - * @param currentPath path currently being considered - * @param parentName name of the parent element - * @param superParentPath path leading to the parent element - * @param pom pom to modify - * @param parentPath path of the parent element - * @param elementName name of the element to set or create - * @param value the new value of the element - * @param shouldCreate should the element be created if it's not found in the first encountered parent element - * matching the parentPath - * @return {@code true} if the element was created or replaced - * @throws XMLStreamException if something went wrong - */ - private static boolean setElementValueInternal( String currentPath, String parentName, - String superParentPath, - ModifiedPomXMLEventReader pom, - String parentPath, String elementName, String value, - boolean shouldCreate ) - throws XMLStreamException - { - boolean replacementMade = false; - while ( !replacementMade && pom.hasNext() ) - { - XMLEvent event = pom.nextEvent(); - if ( event.isStartElement() ) + ElementValueInternal() { - String currentElementName = event.asStartElement().getName().getLocalPart(); - - // start of the "elementName" element - if ( currentPath.equals( parentPath ) && elementName.equals( currentElementName ) ) - { - assert !pom.hasMark( 0 ); - pom.mark( 0 ); - } - // start of the parent - else if ( currentPath.equals( superParentPath ) && currentElementName.equals( parentName ) ) - { - assert !pom.hasMark( 2 ); - pom.mark( 2 ); - } - - // process child element - replacementMade = setElementValueInternal( currentPath + "/" + currentElementName, - parentName, superParentPath, - pom, parentPath, elementName, value, shouldCreate ); + int lastDelimeterIndex = parentPath.lastIndexOf( '/' ); + parentName = parentPath.substring( lastDelimeterIndex + 1 ); + superParentPath = parentPath.substring( 0, lastDelimeterIndex ); } - else if ( event.isEndElement() ) + + boolean process( String currentPath ) throws XMLStreamException { - // end of the "elementName" element - if ( currentPath.equals( parentPath + "/" + elementName ) ) + boolean replacementMade = false; + while ( !replacementMade && pom.hasNext() ) { - assert pom.hasMark( 0 ); - assert !pom.hasMark( 1 ); - pom.mark( 1 ); - - if ( pom.getBetween( 0, 1 ).length() > 0 ) + XMLEvent event = pom.nextEvent(); + if ( event.isStartElement() ) { - pom.replaceBetween( 0, 1, value ); + String currentElementName = event.asStartElement().getName().getLocalPart(); + + // here, we will only mark the beginning of the child or the parent element + if ( currentPath.equals( parentPath ) && elementName.equals( currentElementName ) ) + { + pom.mark( MARK_CHILD_BEGIN ); + } + else if ( currentPath.equals( superParentPath ) && currentElementName.equals( parentName ) ) + { + pom.mark( PARENT_BEGIN ); + } + // process child element + replacementMade = process( currentPath + "/" + currentElementName ); } - else + else if ( event.isEndElement() ) { - pom.replace( String.format( "<%1$s>%2$s", elementName, value ) ); + // here we're doing the replacement + if ( currentPath.equals( parentPath + "/" + elementName ) ) + { + // end of the child + replaceValueInChild(); + replacementMade = true; + } + else if ( shouldCreate && currentPath.equals( parentPath ) ) + { + // end of the parent + replaceValueInParent(); + replacementMade = true; + } + else + { + return false; + } } + } + return replacementMade; + } - replacementMade = true; + private void replaceValueInChild() + { + pom.mark( MARK_OPTION ); + if ( pom.getBetween( MARK_CHILD_BEGIN, MARK_OPTION ).length() > 0 ) + { + pom.replaceBetween( 0, 1, value ); } - // end of the parent - else if ( shouldCreate && currentPath.equals( parentPath ) ) + else { - assert !pom.hasMark( 1 ); - pom.mark( 1 ); + pom.replace( String.format( "<%1$s>%2$s", elementName, value ) ); + } + } - if ( pom.hasMark( 2 ) ) + private void replaceValueInParent() + { + pom.mark( MARK_OPTION ); + if ( pom.hasMark( PARENT_BEGIN ) ) + { + if ( pom.getBetween( PARENT_BEGIN, MARK_OPTION ).length() > 0 ) { - if ( pom.getBetween( 2, 1 ).length() > 0 ) - { - pom.replace( String.format( "<%2$s>%3$s", - parentName, elementName, value ) ); - } - else - { - pom.replace( String.format( "<%1$s><%2$s>%3$s", - parentName, elementName, value ) ); - } + pom.replace( String.format( "<%2$s>%3$s", + parentName, elementName, value ) ); } else { pom.replace( String.format( "<%1$s><%2$s>%3$s", parentName, elementName, value ) ); } - - replacementMade = true; } - - break; + else + { + pom.replace( String.format( "<%1$s><%2$s>%3$s", + parentName, elementName, value ) ); + } } } - return replacementMade; + try + { + pom.rewind(); + return new ElementValueInternal().process( "" ); + } + finally + { + range( 0, 3 ).forEach( pom::clearMark ); + } } /** diff --git a/src/test/java/org/codehaus/mojo/versions/SetScmTagMojoTest.java b/src/test/java/org/codehaus/mojo/versions/SetScmTagMojoTest.java index 8cd9e21a74..db8fae6aef 100644 --- a/src/test/java/org/codehaus/mojo/versions/SetScmTagMojoTest.java +++ b/src/test/java/org/codehaus/mojo/versions/SetScmTagMojoTest.java @@ -19,9 +19,17 @@ * under the License. */ +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + import org.codehaus.mojo.versions.utils.BaseMojoTestCase; import org.junit.Test; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.matchesPattern; + /** * Basic tests for {@linkplain SetPropertyMojoTest}. * @@ -32,9 +40,18 @@ public class SetScmTagMojoTest extends BaseMojoTestCase @Test public void testNewScmValues() throws Exception { - SetScmTagMojo mojo = - createMojo( "set-scm-tag", - "src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml" ); - mojo.execute(); + Path pomFile = Paths.get( "target/test-classes/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml" ); + createMojo( "set-scm-tag", pomFile.toString() ) + .execute(); + String output = String.join( "", Files.readAllLines( pomFile ) ) + .replaceAll( "\\s*", "" ); + assertThat( output, allOf( + matchesPattern( ".*.*\\s*newTag\\s*.*.*" ), + matchesPattern( ".*.*\\s*url\\s*.*.*" ), + matchesPattern( ".*.*\\s*connection\\s*.*.*" ), + matchesPattern( ".*.*\\s*" + + "developerConnection\\s*.*.*" ) + ) + ); } } diff --git a/src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml b/src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml index 1a142445da..681851f29a 100644 --- a/src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml +++ b/src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml @@ -6,6 +6,8 @@ 1.0 pom + + diff --git a/src/test/resources/org/codehaus/mojo/set-scm-tag/pom.xml b/src/test/resources/org/codehaus/mojo/set-scm-tag/pom.xml new file mode 100644 index 0000000000..681851f29a --- /dev/null +++ b/src/test/resources/org/codehaus/mojo/set-scm-tag/pom.xml @@ -0,0 +1,24 @@ + + 4.0.0 + default-group + default-artifact + 1.0 + pom + + + + + + + versions-maven-plugin + + newTag + connection + developerConnection + url + + + + + \ No newline at end of file