Skip to content

Commit

Permalink
Allow for simple re-usable AddPropertyVisitor (#4207)
Browse files Browse the repository at this point in the history
  • Loading branch information
BoykoAlex authored May 22, 2024
1 parent a0c2940 commit e5b2af7
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 61 deletions.
91 changes: 30 additions & 61 deletions rewrite-maven/src/main/java/org/openrewrite/maven/AddProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.*;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Option;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.xml.AddToTagVisitor;
import org.openrewrite.xml.ChangeTagValueVisitor;
import org.openrewrite.xml.TagNameComparator;
import org.openrewrite.xml.tree.Xml;

import java.util.Optional;
Expand Down Expand Up @@ -71,63 +71,32 @@ public String getDescription() {

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new AddPropertyVisitor(
key.replace("${", "").replace("}", ""), value, preserveExistingValue, trustParent);
}
}

@Value
@EqualsAndHashCode(callSuper = false)
class AddPropertyVisitor extends MavenIsoVisitor<ExecutionContext> {
String key;
String value;
@Nullable Boolean preserveExistingValue;
@Nullable Boolean trustParent;

@Override
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
String parentValue = getResolutionResult().getPom().getRequested().getProperties().get(key);
if ((Boolean.TRUE.equals(trustParent) && (parentValue == null || value.equals(parentValue)))
|| value.equals(getResolutionResult().getPom().getProperties().get(key))) {
return document;
}

// If there is a parent pom in the same project, update the property there instead
if (document.getRoot().getChild("parent")
.flatMap(tag -> tag.getChild("relativePath"))
.flatMap(Xml.Tag::getValue)
.isPresent()) {
if (Boolean.TRUE.equals(preserveExistingValue)) {
return document;
final String keyToReplace = key.replace("${", "").replace("}", "");
return new MavenIsoVisitor<ExecutionContext>() {
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
String parentValue = getResolutionResult().getPom().getRequested().getProperties().get(key);
if ((Boolean.TRUE.equals(trustParent) && (parentValue == null || value.equals(parentValue)))
|| value.equals(getResolutionResult().getPom().getProperties().get(key))) {
return document;
}

// If there is a parent pom in the same project, update the property there instead
if (document.getRoot().getChild("parent")
.flatMap(tag -> tag.getChild("relativePath"))
.flatMap(Xml.Tag::getValue)
.flatMap(v -> v.trim().isEmpty() ? Optional.empty() : Optional.of(v))
.isPresent()) {
if (Boolean.TRUE.equals(preserveExistingValue)) {
return document;
}
// If the property is expected to be in the parent, there's no need for it in the child pom
return (Xml.Document) new RemoveProperty(key).getVisitor()
.visitNonNull(document, ctx);
}
return (Xml.Document) new AddPropertyVisitor(keyToReplace, value, preserveExistingValue)
.visitNonNull(document, ctx);
}
// If the property is expected to be in the parent, there's no need for it in the child pom
return (Xml.Document) new RemoveProperty(key).getVisitor()
.visitNonNull(document, ctx);
}

Xml.Document d = super.visitDocument(document, ctx);
Xml.Tag root = d.getRoot();
Optional<Xml.Tag> properties = root.getChild("properties");
if (!properties.isPresent()) {
Xml.Tag propertiesTag = Xml.Tag.build("<properties>\n<" + key + ">" + value + "</" + key + ">\n</properties>");
d = (Xml.Document) new AddToTagVisitor<ExecutionContext>(root, propertiesTag, new MavenTagInsertionComparator(root.getChildren())).visitNonNull(d, ctx);
} else if (!properties.get().getChildValue(key).isPresent()) {
Xml.Tag propertyTag = Xml.Tag.build("<" + key + ">" + value + "</" + key + ">");
d = (Xml.Document) new AddToTagVisitor<>(properties.get(), propertyTag, new TagNameComparator()).visitNonNull(d, ctx);
}
if (d != document) {
maybeUpdateModel();
}
return d;
}

@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if (!Boolean.TRUE.equals(preserveExistingValue)
&& isPropertyTag() && key.equals(tag.getName())
&& !value.equals(tag.getValue().orElse(null))) {
doAfterVisit(new ChangeTagValueVisitor<>(tag, value));
}
return super.visitTag(tag, ctx);
};
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2022 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.maven;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.ExecutionContext;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.xml.AddToTagVisitor;
import org.openrewrite.xml.ChangeTagValueVisitor;
import org.openrewrite.xml.TagNameComparator;
import org.openrewrite.xml.tree.Xml;

import java.util.Optional;

@Value
@EqualsAndHashCode(callSuper = false)
public class AddPropertyVisitor extends MavenIsoVisitor<ExecutionContext> {
String key;
String value;
@Nullable Boolean preserveExistingValue;

@Override
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
Xml.Document d = super.visitDocument(document, ctx);
Xml.Tag root = d.getRoot();
Optional<Xml.Tag> properties = root.getChild("properties");
if (!properties.isPresent()) {
Xml.Tag propertiesTag = Xml.Tag.build("<properties>\n<" + key + ">" + value + "</" + key + ">\n</properties>");
d = (Xml.Document) new AddToTagVisitor<ExecutionContext>(root, propertiesTag, new MavenTagInsertionComparator(root.getChildren())).visitNonNull(d, ctx);
} else if (!properties.get().getChildValue(key).isPresent()) {
Xml.Tag propertyTag = Xml.Tag.build("<" + key + ">" + value + "</" + key + ">");
d = (Xml.Document) new AddToTagVisitor<>(properties.get(), propertyTag, new TagNameComparator()).visitNonNull(d, ctx);
}
if (d != document) {
maybeUpdateModel();
}
return d;
}

@Override
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if (!Boolean.TRUE.equals(preserveExistingValue)
&& isPropertyTag() && key.equals(tag.getName())
&& !value.equals(tag.getValue().orElse(null))) {
doAfterVisit(new ChangeTagValueVisitor<>(tag, value));
}
return super.visitTag(tag, ctx);
}
}
109 changes: 109 additions & 0 deletions rewrite-maven/src/test/java/org/openrewrite/maven/AddPropertyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,115 @@ void trustParent() {
);
}

@Test
void ifRemoteParentIsDefined() {
rewriteRun(
pomXml(
"""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
</project>
""","""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
<properties>
<key>value</key>
</properties>
</project>
"""

)
);
}

@Test
void ifRemoteParentIsDefined_2() {
rewriteRun(
pomXml(
"""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath></relativePath>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
</project>
""","""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath></relativePath>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
<properties>
<key>value</key>
</properties>
</project>
"""

)
);
}

@Test
void ifRemoteParentIsDefined_3() {
rewriteRun(
pomXml(
"""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
</project>
""","""
<project>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.2</version>
<relativePath/>
</parent>
<groupId>com.mycompany.app</groupId>
<artifactId>my-parent</artifactId>
<version>1</version>
<properties>
<key>value</key>
</properties>
</project>
"""

)
);
}

@DocumentExample
@Test
void addFirstProperty() {
Expand Down

0 comments on commit e5b2af7

Please sign in to comment.