From bc39e9546de7fbd00c965f9b111843555813b310 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Mon, 21 Oct 2024 15:08:19 +0200 Subject: [PATCH 1/5] WIP setup for adding JavaType marker after parsing --- .../java/org/openrewrite/xml/XmlParser.java | 39 +++++++++++++++++-- .../org/openrewrite/xml/marker/JavaType.java | 13 +++++++ .../org/openrewrite/xml/XmlParserTest.java | 37 ++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java index f99abd38118..26cc7d26b7c 100755 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java @@ -29,12 +29,12 @@ import org.openrewrite.xml.internal.XmlParserVisitor; import org.openrewrite.xml.internal.grammar.XMLLexer; import org.openrewrite.xml.internal.grammar.XMLParser; +import org.openrewrite.xml.marker.JavaType; import org.openrewrite.xml.tree.Xml; import java.nio.file.Path; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import java.util.*; +import java.util.regex.Pattern; import java.util.stream.Stream; public class XmlParser implements Parser { @@ -94,6 +94,7 @@ public Stream parseInputs(Iterable sourceFiles, @Nullable Pat is.isCharsetBomMarked() ).visitDocument(parser.document()); parsingListener.parsed(input, document); + document = (Xml.Document) addJavaTypeOrPackageMarkers().visitDocument(document, ctx); return requirePrintEqualsInput(document, input, relativeTo, ctx); } catch (Throwable t) { ctx.getOnError().accept(t); @@ -161,4 +162,36 @@ public String getDslName() { return "xml"; } } + + private XmlVisitor addJavaTypeOrPackageMarkers(){ + final Pattern PACKAGE_OR_TYPE_REFERENCE = Pattern.compile("^([a-zA-Z_][a-zA-Z0-9_]*)(\\.[a-zA-Z_][a-zA-Z0-9_]*)*(\\.[A-Z][a-zA-Z0-9_]*|\\$[A-Z][a-zA-Z0-9_]*)*(\\.\\*)?$"); + final List ATTRIBUTES_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("class", "type"); + final List TAGS_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("value"); + + return new XmlVisitor() { + @Override + public Xml visitAttribute(Xml.Attribute attribute, ExecutionContext ctx) { + Xml.Attribute attrib = (Xml.Attribute) super.visitAttribute(attribute, ctx); + if (ATTRIBUTES_THAT_REFERENCE_PACKAGE_OR_TYPE.contains(attrib.getKey().getName())) { + if (PACKAGE_OR_TYPE_REFERENCE.matcher(attrib.getValueAsString()).matches()) { + return attrib.withMarkers(attrib.getMarkers().withMarkers(Collections.singletonList(new JavaType(attrib.getId())))); + } + } + return attrib; + } + + @Override + public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { + Xml.Tag tg = (Xml.Tag) super.visitTag(tag, ctx); + if (TAGS_THAT_REFERENCE_PACKAGE_OR_TYPE.contains(tg.getName())) { + if (tg.getValue().isPresent()) { + if (PACKAGE_OR_TYPE_REFERENCE.matcher(tg.getValue().get()).matches()) { + return tg.withMarkers(tg.getMarkers().withMarkers(Collections.singletonList(new JavaType(tg.getId())))); + } + } + } + return tg; + } + }; + } } diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java b/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java new file mode 100644 index 00000000000..777b398b18d --- /dev/null +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java @@ -0,0 +1,13 @@ +package org.openrewrite.xml.marker; + +import lombok.Value; +import lombok.With; +import org.openrewrite.marker.Marker; + +import java.util.UUID; + +@Value +@With +public class JavaType implements Marker { + UUID id; +} diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java index 1c7449d6639..316ef25d813 100755 --- a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java +++ b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java @@ -24,12 +24,14 @@ import org.openrewrite.Issue; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.xml.marker.JavaType; import org.openrewrite.xml.tree.Xml; import java.nio.file.Paths; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.openrewrite.test.RewriteTest.toRecipe; import static org.openrewrite.xml.Assertions.xml; @@ -397,6 +399,41 @@ void preserveWhitespaceOnEntities() { ); } + @Test + void springXmlMarkers() { + rewriteRun( + xml( + """ + + + + + + + + + java.lang.String + + + + + + """, + spec -> spec.afterRecipe(after -> { + Xml.Tag testBean = ((Xml.Tag)after.getRoot().getContent().get(0)); + assertTrue(testBean.getAttributes().get(1).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + Xml.Tag unnamedBeanInSiblingProperty = ((Xml.Tag)((Xml.Tag)testBean.getContent().get(1)).getContent().get(0)); + assertTrue(unnamedBeanInSiblingProperty.getAttributes().get(0).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + Xml.Tag ageProperty = ((Xml.Tag)unnamedBeanInSiblingProperty.getContent().get(0)); + assertTrue(ageProperty.getAttributes().get(2).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + Xml.Tag someNameValue = (Xml.Tag) ((Xml.Tag)unnamedBeanInSiblingProperty.getContent().get(1)).getContent().get(0); + assertTrue(someNameValue.getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + }) + ) + ); + } + @DisabledOnOs(OS.WINDOWS) @ParameterizedTest @ValueSource(strings = { From 4b1e85ee11c803ff6252d5a809918b4f72bf4ec1 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Mon, 21 Oct 2024 15:58:23 +0200 Subject: [PATCH 2/5] FMT --- .../src/main/java/org/openrewrite/xml/XmlParser.java | 2 +- .../src/test/java/org/openrewrite/xml/XmlParserTest.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java index 26cc7d26b7c..b075a591357 100755 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java @@ -163,7 +163,7 @@ public String getDslName() { } } - private XmlVisitor addJavaTypeOrPackageMarkers(){ + private XmlVisitor addJavaTypeOrPackageMarkers() { final Pattern PACKAGE_OR_TYPE_REFERENCE = Pattern.compile("^([a-zA-Z_][a-zA-Z0-9_]*)(\\.[a-zA-Z_][a-zA-Z0-9_]*)*(\\.[A-Z][a-zA-Z0-9_]*|\\$[A-Z][a-zA-Z0-9_]*)*(\\.\\*)?$"); final List ATTRIBUTES_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("class", "type"); final List TAGS_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("value"); diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java index 316ef25d813..075fabd5e46 100755 --- a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java +++ b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java @@ -421,13 +421,13 @@ void springXmlMarkers() { """, spec -> spec.afterRecipe(after -> { - Xml.Tag testBean = ((Xml.Tag)after.getRoot().getContent().get(0)); + Xml.Tag testBean = ((Xml.Tag) after.getRoot().getContent().get(0)); assertTrue(testBean.getAttributes().get(1).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); - Xml.Tag unnamedBeanInSiblingProperty = ((Xml.Tag)((Xml.Tag)testBean.getContent().get(1)).getContent().get(0)); + Xml.Tag unnamedBeanInSiblingProperty = ((Xml.Tag) ((Xml.Tag) testBean.getContent().get(1)).getContent().get(0)); assertTrue(unnamedBeanInSiblingProperty.getAttributes().get(0).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); - Xml.Tag ageProperty = ((Xml.Tag)unnamedBeanInSiblingProperty.getContent().get(0)); + Xml.Tag ageProperty = ((Xml.Tag) unnamedBeanInSiblingProperty.getContent().get(0)); assertTrue(ageProperty.getAttributes().get(2).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); - Xml.Tag someNameValue = (Xml.Tag) ((Xml.Tag)unnamedBeanInSiblingProperty.getContent().get(1)).getContent().get(0); + Xml.Tag someNameValue = (Xml.Tag) ((Xml.Tag) unnamedBeanInSiblingProperty.getContent().get(1)).getContent().get(0); assertTrue(someNameValue.getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); }) ) From 4e3b4fa3f094e6f1aaa9fc886928ce2067c7f020 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 22 Oct 2024 10:31:21 +0200 Subject: [PATCH 3/5] Update rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../java/org/openrewrite/xml/marker/JavaType.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java b/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java index 777b398b18d..7671bfe03c5 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.xml.marker; import lombok.Value; From 6e34443c5815c8187a8a721926c179865f74c597 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 22 Oct 2024 11:39:23 +0200 Subject: [PATCH 4/5] WIP --- .../org/openrewrite/marker/TypeReference.java | 6 ++-- .../java/org/openrewrite/xml/XmlParser.java | 28 +++++++++---------- .../org/openrewrite/xml/XmlParserTest.java | 10 +++---- 3 files changed, 22 insertions(+), 22 deletions(-) rename rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java => rewrite-core/src/main/java/org/openrewrite/marker/TypeReference.java (86%) diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java b/rewrite-core/src/main/java/org/openrewrite/marker/TypeReference.java similarity index 86% rename from rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java rename to rewrite-core/src/main/java/org/openrewrite/marker/TypeReference.java index 7671bfe03c5..ebe88df0884 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/marker/JavaType.java +++ b/rewrite-core/src/main/java/org/openrewrite/marker/TypeReference.java @@ -13,16 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openrewrite.xml.marker; +package org.openrewrite.marker; import lombok.Value; import lombok.With; -import org.openrewrite.marker.Marker; import java.util.UUID; @Value @With -public class JavaType implements Marker { +public class TypeReference implements Marker { UUID id; + String language; } diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java index b075a591357..5d9c5690b0a 100755 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java @@ -23,18 +23,20 @@ import org.openrewrite.Parser; import org.openrewrite.SourceFile; import org.openrewrite.internal.EncodingDetectingInputStream; +import org.openrewrite.marker.TypeReference; import org.openrewrite.tree.ParseError; import org.openrewrite.tree.ParsingEventListener; import org.openrewrite.tree.ParsingExecutionContextView; import org.openrewrite.xml.internal.XmlParserVisitor; import org.openrewrite.xml.internal.grammar.XMLLexer; import org.openrewrite.xml.internal.grammar.XMLParser; -import org.openrewrite.xml.marker.JavaType; import org.openrewrite.xml.tree.Xml; import java.nio.file.Path; -import java.util.*; -import java.util.regex.Pattern; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import java.util.stream.Stream; public class XmlParser implements Parser { @@ -164,18 +166,18 @@ public String getDslName() { } private XmlVisitor addJavaTypeOrPackageMarkers() { - final Pattern PACKAGE_OR_TYPE_REFERENCE = Pattern.compile("^([a-zA-Z_][a-zA-Z0-9_]*)(\\.[a-zA-Z_][a-zA-Z0-9_]*)*(\\.[A-Z][a-zA-Z0-9_]*|\\$[A-Z][a-zA-Z0-9_]*)*(\\.\\*)?$"); - final List ATTRIBUTES_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("class", "type"); - final List TAGS_THAT_REFERENCE_PACKAGE_OR_TYPE = Arrays.asList("value"); + XPathMatcher classXPath = new XPathMatcher("//@class[contains(., '.')]"); + XPathMatcher typeXPath = new XPathMatcher("//@type[contains(., '.')]"); + XPathMatcher tags = new XPathMatcher("//value[contains(text(), '.')]"); return new XmlVisitor() { + @Override public Xml visitAttribute(Xml.Attribute attribute, ExecutionContext ctx) { Xml.Attribute attrib = (Xml.Attribute) super.visitAttribute(attribute, ctx); - if (ATTRIBUTES_THAT_REFERENCE_PACKAGE_OR_TYPE.contains(attrib.getKey().getName())) { - if (PACKAGE_OR_TYPE_REFERENCE.matcher(attrib.getValueAsString()).matches()) { - return attrib.withMarkers(attrib.getMarkers().withMarkers(Collections.singletonList(new JavaType(attrib.getId())))); - } + if (classXPath.matches(getCursor()) || typeXPath.matches(getCursor())) { + return attrib.withMarkers(attrib.getMarkers().withMarkers(Collections.singletonList(new TypeReference(attrib.getId(), "Java")))); + } return attrib; } @@ -183,11 +185,9 @@ public Xml visitAttribute(Xml.Attribute attribute, ExecutionContext ctx) { @Override public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) { Xml.Tag tg = (Xml.Tag) super.visitTag(tag, ctx); - if (TAGS_THAT_REFERENCE_PACKAGE_OR_TYPE.contains(tg.getName())) { + if (tags.matches(getCursor())) { if (tg.getValue().isPresent()) { - if (PACKAGE_OR_TYPE_REFERENCE.matcher(tg.getValue().get()).matches()) { - return tg.withMarkers(tg.getMarkers().withMarkers(Collections.singletonList(new JavaType(tg.getId())))); - } + return tg.withMarkers(tg.getMarkers().withMarkers(Collections.singletonList(new TypeReference(tg.getId(), "Java")))); } } return tg; diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java index 075fabd5e46..f2ccda6627f 100755 --- a/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java +++ b/rewrite-xml/src/test/java/org/openrewrite/xml/XmlParserTest.java @@ -22,9 +22,9 @@ import org.junit.jupiter.params.provider.ValueSource; import org.openrewrite.ExecutionContext; import org.openrewrite.Issue; +import org.openrewrite.marker.TypeReference; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; -import org.openrewrite.xml.marker.JavaType; import org.openrewrite.xml.tree.Xml; import java.nio.file.Paths; @@ -422,13 +422,13 @@ void springXmlMarkers() { """, spec -> spec.afterRecipe(after -> { Xml.Tag testBean = ((Xml.Tag) after.getRoot().getContent().get(0)); - assertTrue(testBean.getAttributes().get(1).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + assertTrue(testBean.getAttributes().get(1).getMarkers().getMarkers().stream().anyMatch(TypeReference.class::isInstance)); Xml.Tag unnamedBeanInSiblingProperty = ((Xml.Tag) ((Xml.Tag) testBean.getContent().get(1)).getContent().get(0)); - assertTrue(unnamedBeanInSiblingProperty.getAttributes().get(0).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + assertTrue(unnamedBeanInSiblingProperty.getAttributes().get(0).getMarkers().getMarkers().stream().anyMatch(TypeReference.class::isInstance)); Xml.Tag ageProperty = ((Xml.Tag) unnamedBeanInSiblingProperty.getContent().get(0)); - assertTrue(ageProperty.getAttributes().get(2).getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + assertTrue(ageProperty.getAttributes().get(2).getMarkers().getMarkers().stream().anyMatch(TypeReference.class::isInstance)); Xml.Tag someNameValue = (Xml.Tag) ((Xml.Tag) unnamedBeanInSiblingProperty.getContent().get(1)).getContent().get(0); - assertTrue(someNameValue.getMarkers().getMarkers().stream().anyMatch(JavaType.class::isInstance)); + assertTrue(someNameValue.getMarkers().getMarkers().stream().anyMatch(TypeReference.class::isInstance)); }) ) ); From 1fdc1de518e82c7dc5f8429766b37c22ae26de04 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 22 Oct 2024 14:37:38 +0200 Subject: [PATCH 5/5] Only select spring xml files for now --- .../main/java/org/openrewrite/xml/XmlParser.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java index 5d9c5690b0a..055a02424dd 100755 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/XmlParser.java @@ -96,7 +96,9 @@ public Stream parseInputs(Iterable sourceFiles, @Nullable Pat is.isCharsetBomMarked() ).visitDocument(parser.document()); parsingListener.parsed(input, document); - document = (Xml.Document) addJavaTypeOrPackageMarkers().visitDocument(document, ctx); + if (isSpringXmlDocument(document)) { + document = (Xml.Document) addJavaTypeOrPackageMarkers().visitDocument(document, ctx); + } return requirePrintEqualsInput(document, input, relativeTo, ctx); } catch (Throwable t) { ctx.getOnError().accept(t); @@ -105,6 +107,15 @@ public Stream parseInputs(Iterable sourceFiles, @Nullable Pat }); } + private boolean isSpringXmlDocument(Xml.Document document) { + for (Xml.Attribute attrib : document.getRoot().getAttributes()) { + if (attrib.getKeyAsString().equals("xsi:schemaLocation") && attrib.getValueAsString().contains("www.springframework.org/schema/beans")) { + return true; + } + } + return false; + } + @Override public Stream parse(@Language("xml") String... sources) { return parse(new InMemoryExecutionContext(), sources);