Skip to content

Commit

Permalink
Add XSLT transformation recipe (#3606)
Browse files Browse the repository at this point in the history
* Add XSLT transformation recipe

* Update rewrite-maven/src/main/java/org/openrewrite/maven/ChangePluginConfiguration.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-maven/src/main/java/org/openrewrite/maven/ChangePluginConfiguration.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-xml/src/main/java/org/openrewrite/xml/XsltTransformation.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-xml/src/main/java/org/openrewrite/xml/XsltTransformationVisitor.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-xml/src/main/java/org/openrewrite/xml/XsltTransformationVisitor.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-xml/src/main/java/org/openrewrite/xml/XsltTransformationVisitor.java

Co-authored-by: Tim te Beek <[email protected]>

* Update rewrite-xml/src/main/java/org/openrewrite/xml/XsltTransformationVisitor.java

Co-authored-by: Tim te Beek <[email protected]>

* Fix merge issues

* Update build.gradle.kts

* Fix compilation errors

* Add example values as suggested

* Complete XsltTransformation description

* Apply suggestions from code review

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Shorten and harden either/or validation

* Small changes for consistency

* Validate that configuration is set at most once

---------

Co-authored-by: Tim te Beek <[email protected]>
Co-authored-by: Jonathan Schnéider <[email protected]>
Co-authored-by: Tim te Beek <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
5 people authored Jul 14, 2024
1 parent 6810d2f commit c24ec1c
Show file tree
Hide file tree
Showing 7 changed files with 525 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,21 @@
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.intellij.lang.annotations.Language;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Option;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.*;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.xml.XPathMatcher;
import org.openrewrite.xml.XsltTransformation;
import org.openrewrite.xml.XsltTransformationVisitor;
import org.openrewrite.xml.tree.Xml;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Optional;
import java.util.stream.Stream;

import static java.util.Objects.requireNonNull;
import static org.openrewrite.xml.AddOrUpdateChild.addOrUpdateChild;
import static org.openrewrite.xml.FilterTagChildrenVisitor.filterChildren;

Expand All @@ -54,6 +59,21 @@ public class ChangePluginConfiguration extends Recipe {
@Nullable
String configuration;

@Nullable
@Language("xml")
@Option(displayName = "XSLT Configuration transformation",
description = "The transformation to be applied on the <configuration> element.",
example = "<xsl:stylesheet ...>...</xsl:stylesheet>",
required = false)
String xslt;

@Nullable
@Option(displayName = "XSLT Configuration transformation classpath resource",
description = "The transformation to be applied on the <configuration> element provided as a classpath resource.",
example = "/changePlugin.xslt",
required = false)
String xsltResource;

@Override
public String getDisplayName() {
return "Change Maven plugin configuration";
Expand All @@ -69,6 +89,12 @@ public String getDescription() {
return "Apply the specified configuration to a Maven plugin. Will not add the plugin if it does not already exist in the pom.";
}

@Override
public Validated<Object> validate() {
return super.validate().and(Validated.test("configuration", "Configuration set at most once", configuration,
cfg -> Stream.of(configuration, xslt, xsltResource).filter(StringUtils::isBlank).count() >= 2));
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new MavenVisitor<ExecutionContext>() {
Expand All @@ -79,24 +105,45 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
Optional<Xml.Tag> maybePlugin = plugins.getChildren().stream()
.filter(plugin ->
"plugin".equals(plugin.getName()) &&
groupId.equals(plugin.getChildValue("groupId").orElse(null)) &&
artifactId.equals(plugin.getChildValue("artifactId").orElse(null))
groupId.equals(plugin.getChildValue("groupId").orElse(null)) &&
artifactId.equals(plugin.getChildValue("artifactId").orElse(null))
)
.findAny();
if (maybePlugin.isPresent()) {
Xml.Tag plugin = maybePlugin.get();
if (configuration == null) {
if (configuration == null && xslt == null && xsltResource == null) {
plugins = filterChildren(plugins, plugin,
child -> !(child instanceof Xml.Tag && "configuration".equals(((Xml.Tag) child).getName())));
} else {
} else if (configuration != null) {
plugins = addOrUpdateChild(plugins, plugin,
Xml.Tag.build("<configuration>\n" + configuration + "\n</configuration>"),
getCursor().getParentOrThrow());
} else {
// Implied that xslt or xsltResource is not null
Optional<Xml.Tag> configurationTag = plugin.getChild("configuration");
if (configurationTag.isPresent()) {
String xsltTransformation = loadResource(xslt, xsltResource);
plugins = addOrUpdateChild(plugins, plugin,
XsltTransformationVisitor.transformTag(configurationTag.get().printTrimmed(getCursor()), xsltTransformation),
getCursor().getParentOrThrow());
}
}
}
}
return plugins;
}
};
}

private static String loadResource(@Nullable String xslt, @Nullable String xsltResource) {
if (StringUtils.isBlank(xsltResource)) {
return requireNonNull(xslt);
}
try (InputStream is = XsltTransformation.class.getResourceAsStream(xsltResource)) {
assert is != null;
return StringUtils.readFully(is, Charset.defaultCharset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,41 @@
*/
package org.openrewrite.maven;

import org.intellij.lang.annotations.Language;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.test.RewriteTest;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.openrewrite.maven.Assertions.pomXml;

class ChangePluginConfigurationTest implements RewriteTest {

@Language("xml")
private static String xslt;

@BeforeAll
static void setup() {
xslt = StringUtils.readFully(ChangePluginConfigurationTest.class
.getResourceAsStream("/changePlugin.xslt"));

assertFalse(StringUtils.isBlank(xslt));
}

@DocumentExample
@Test
void removeConfiguration() {
rewriteRun(
spec -> spec.recipe(new ChangePluginConfiguration("org.openrewrite.maven", "rewrite-maven-plugin", null)),
spec -> spec.recipe(new ChangePluginConfiguration("org.openrewrite.maven", "rewrite-maven-plugin", null, null, null)),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -56,7 +71,7 @@ void removeConfiguration() {
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -78,14 +93,16 @@ void addConfiguration() {
spec -> spec.recipe(new ChangePluginConfiguration(
"org.openrewrite.maven",
"rewrite-maven-plugin",
"<activeRecipes>\n<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>\n</activeRecipes>")),
"<activeRecipes>\n<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>\n</activeRecipes>",
null,
null)),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -102,7 +119,7 @@ void addConfiguration() {
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -129,14 +146,16 @@ void replaceConfiguration() {
spec -> spec.recipe(new ChangePluginConfiguration(
"org.openrewrite.maven",
"rewrite-maven-plugin",
"<activeRecipes>\n<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>\n</activeRecipes>")),
"<activeRecipes>\n<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>\n</activeRecipes>",
null,
null)),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -154,7 +173,43 @@ void replaceConfiguration() {
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>4.1.5</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>
</activeRecipes>
</configuration>
</plugin>
</plugins>
</build>
</project>
"""
)
);
}

@Test
void transformConfigurationFromInlineTransformation() {
rewriteRun(
spec -> spec.recipe(new ChangePluginConfiguration(
"org.openrewrite.maven",
"rewrite-maven-plugin",
null,
xslt,
null)),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
Expand All @@ -170,6 +225,117 @@ void replaceConfiguration() {
</plugins>
</build>
</project>
""",
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>4.1.5</version>
<configuration>
<activeRecipes>
<activeRecipe>org.openrewrite.java.cleanup.UnnecessaryThrows</activeRecipe>
</activeRecipes>
</configuration>
</plugin>
</plugins>
</build>
</project>
"""
)
);
}

@Test
void transformConfigurationFromClasspathResource() {
rewriteRun(
spec -> spec.recipe(new ChangePluginConfiguration(
"org.openrewrite.maven",
"rewrite-maven-plugin",
null,
null,
"/changePlugin.xslt")),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>4.1.5</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.cleanup.UnnecessaryThrows</recipe>
</activeRecipes>
</configuration>
</plugin>
</plugins>
</build>
</project>
""",
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>4.1.5</version>
<configuration>
<activeRecipes>
<activeRecipe>org.openrewrite.java.cleanup.UnnecessaryThrows</activeRecipe>
</activeRecipes>
</configuration>
</plugin>
</plugins>
</build>
</project>
"""
)
);
}

@Test
void transformConfigurationNoOpWhenConfigurationMissing() {
rewriteRun(
spec -> spec.recipe(new ChangePluginConfiguration(
"org.openrewrite.maven",
"rewrite-maven-plugin",
null,
null,
null)),
pomXml(
"""
<project>
<groupId>org.example</groupId>
<artifactId>foo</artifactId>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>4.1.5</version>
</plugin>
</plugins>
</build>
</project>
"""
)
);
Expand Down
15 changes: 15 additions & 0 deletions rewrite-maven/src/test/resources/changePlugin.xslt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="recipe">
<activeRecipe>
<xsl:value-of select="current()"/>
</activeRecipe>
</xsl:template>

</xsl:stylesheet>
Loading

0 comments on commit c24ec1c

Please sign in to comment.