Skip to content

Commit

Permalink
Add TypeReference trait to identify Java type references in XML (#4587
Browse files Browse the repository at this point in the history
)

* Initial setup

* Use XPathMatcher before checking value

* Add JavaTypeReferences to Xml.Document similar to TypesInUse on J.CompilationUnit

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

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

* Small naming fix

* Make setup more generic

* Add license

* Implement ServiceLoader pattern to be able to dynamically provide implementations that detect JavaTypeReference's on source files

* Round of self review

* Apply most of the feedback

* Apply most of the feedback

* Missed a few refactor spots

* Missed another

* Impl has to be public

* Rename

* More feedback

* Merge `SpringTypeReferenceProvider` into `SpringTypeReference` (#4643)

* Merge `SpringTypeReferenceProvider` into `SprintTypeReference`

* Also rename `getJavaTypeReferences()`

* Add code to support `TypeReference` in `UsesType` and `FindTypes`

* Add missing `FindTypesTest`

* Make TypeReferences a nested class of SourceFileWithTypeReferences

* Update rewrite-java/src/main/java/org/openrewrite/java/search/FindTypes.java

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

* Remove unused `TypeReference` methods

* Rename `Xml.Document#javaTypeReferences` field

* Add `@Incubating` annotations

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Knut Wannheden <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent 11cb9db commit 47974da
Show file tree
Hide file tree
Showing 13 changed files with 543 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2024 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;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.openrewrite.trait.TypeReference;

import java.util.*;

@Incubating(since = "8.39.0")
public interface SourceFileWithTypeReferences extends SourceFile {

TypeReferences getTypeReferences();

@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
class TypeReferences {
private final SourceFile sourceFile;
private final Set<TypeReference> typeReferences;

public Collection<TypeReference> findMatches(TypeReference.Matcher matcher) {
List<TypeReference> list = new ArrayList<>();
for (TypeReference ref : typeReferences) {
if (ref.matches(matcher)) {
list.add(ref);
}
}
return list;
}

public static TypeReferences build(SourceFile sourceFile) {
Set<TypeReference> typeReferences = new HashSet<>();
ServiceLoader<TypeReference.Provider> loader = ServiceLoader.load(TypeReference.Provider.class);
loader.forEach(provider -> {
if (provider.isAcceptable(sourceFile)) {
typeReferences.addAll(provider.getTypeReferences(sourceFile));
}
});
return new TypeReferences(sourceFile, typeReferences);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2024 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;

import org.openrewrite.trait.TypeReference;

import java.util.Set;

public interface TypeReferenceProvider {

Set<TypeReference> getTypeReferences(SourceFile sourceFile);

boolean isAcceptable(SourceFile sourceFile);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 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.trait;

import org.openrewrite.Incubating;
import org.openrewrite.SourceFile;
import org.openrewrite.Tree;

import java.util.Set;

@Incubating(since = "8.39.0")
public interface TypeReference extends Trait<Tree> {

String getName();

default boolean matches(Matcher matcher) {
return matcher.matchesName(getName());
}

interface Provider {

Set<TypeReference> getTypeReferences(SourceFile sourceFile);

boolean isAcceptable(SourceFile sourceFile);
}

interface Matcher {
boolean matchesName(String name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.java.Assertions.java;
import static org.openrewrite.xml.Assertions.xml;

@SuppressWarnings("RedundantThrows")
class FindTypesTest implements RewriteTest {
Expand Down Expand Up @@ -426,6 +427,49 @@ class B {
);
}

@Test
void springXml() {
rewriteRun(
spec -> spec.recipe(new FindTypes("a.A1", false)),
xml(
"""
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testBean" class="a.A1" scope="prototype">
<property name="age" value="10"/>
<property name="sibling">
<bean class="a.A1">
<property name="age" value="11" class="java.lang.Integer"/>
<property name="someName">
<value>a.A1</value>
</property>
</bean>
</property>
</bean>
</beans>
""",
"""
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="testBean" <!--~~>-->class="a.A1" scope="prototype">
<property name="age" value="10"/>
<property name="sibling">
<bean <!--~~>-->class="a.A1">
<property name="age" value="11" class="java.lang.Integer"/>
<property name="someName">
<!--~~>--><value>a.A1</value>
</property>
</bean>
</property>
</bean>
</beans>
"""
)
);
}

@Test
void javadocComment() {
rewriteRun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,17 @@ public String getDescription() {

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
JavaIsoVisitor<ExecutionContext> condition = new JavaIsoVisitor<ExecutionContext>() {
TreeVisitor<?, ExecutionContext> condition = new TreeVisitor<Tree, ExecutionContext>() {
@Override
public J visit(@Nullable Tree tree, ExecutionContext ctx) {
public @Nullable Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
if (tree instanceof JavaSourceFile) {
JavaSourceFile cu = (JavaSourceFile) requireNonNull(tree);
if (!Boolean.TRUE.equals(ignoreDefinition) && containsClassDefinition(cu, oldFullyQualifiedTypeName)) {
return SearchResult.found(cu);
}
return new UsesType<>(oldFullyQualifiedTypeName, true).visitNonNull(cu, ctx);
}
return (J) tree;
return tree;
}
};

Expand Down Expand Up @@ -573,7 +573,7 @@ private String fqnToPath(String fullyQualifiedName) {

private boolean updatePath(JavaSourceFile sf, String oldPath, String newPath) {
return !oldPath.equals(newPath) && sf.getClasses().stream()
.anyMatch(o -> !J.Modifier.hasModifier(o.getModifiers(), J.Modifier.Type.Private) &&
.anyMatch(o -> !o.hasModifier(J.Modifier.Type.Private) &&
o.getType() != null && !o.getType().getFullyQualifiedName().contains("$") &&
TypeUtils.isOfClassType(o.getType(), getTopLevelClassName(originalType).getFullyQualifiedName()));
}
Expand Down
10 changes: 8 additions & 2 deletions rewrite-java/src/main/java/org/openrewrite/java/TypeMatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
import org.openrewrite.java.tree.JavaType;
import org.openrewrite.java.tree.TypeTree;
import org.openrewrite.java.tree.TypeUtils;
import org.openrewrite.trait.TypeReference;

import java.util.regex.Pattern;

import static org.openrewrite.java.tree.TypeUtils.fullyQualifiedNamesAreEqual;

@Getter
public class TypeMatcher {
public class TypeMatcher implements TypeReference.Matcher {
private static final String ASPECTJ_DOT_PATTERN = StringUtils.aspectjNameToPattern(".");

@SuppressWarnings("NotNullFieldNotInitialized")
Expand All @@ -54,7 +55,7 @@ public TypeMatcher(@Nullable String fieldType) {
this(fieldType, false);
}

public @Nullable TypeMatcher(@Nullable String fieldType, boolean matchInherited) {
public TypeMatcher(@Nullable String fieldType, boolean matchInherited) {
this.signature = fieldType == null ? ".*" : fieldType;
this.matchInherited = matchInherited;

Expand Down Expand Up @@ -109,4 +110,9 @@ private static boolean isPlainIdentifier(MethodSignatureParser.TargetTypePattern
context.classNameOrInterface().DOTDOT().isEmpty() &&
context.classNameOrInterface().WILDCARD().isEmpty();
}

@Override
public boolean matchesName(String name) {
return matchesTargetTypeName(name);
}
}
Loading

0 comments on commit 47974da

Please sign in to comment.