Browse Source

Polishing.

Use getPackageName() instead of getPackage().getName(), remove essentially duplicate tests and fix array type handling of Q types by using the arrays component type for assignability checks.

Original Pull Request: #3284
pull/3309/head
Christoph Strobl 7 months ago
parent
commit
f28a2c2052
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 21
      src/main/java/org/springframework/data/util/QTypeContributor.java
  2. 23
      src/test/java/QTypeInDefaultPackage.java
  3. 62
      src/test/java/org/springframework/data/util/QTypeContributorUnitTests.java

21
src/main/java/org/springframework/data/util/QTypeContributor.java

@ -18,11 +18,11 @@ package org.springframework.data.util; @@ -18,11 +18,11 @@ package org.springframework.data.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.TypeReference;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
/**
* @author Christoph Strobl
@ -38,18 +38,20 @@ public class QTypeContributor { @@ -38,18 +38,20 @@ public class QTypeContributor {
Class<?> entityPathType = getEntityPathType(classLoader);
if (entityPathType == null) {
return;
}
if (type.isPrimitive() || type.isArray()) {
if (entityPathType == null || type.isPrimitive()) {
return;
}
String queryClassName = getQueryClassName(type);
if (ClassUtils.isPresent(queryClassName, classLoader)) {
if (ClassUtils.isAssignable(entityPathType, ClassUtils.forName(queryClassName, classLoader))) {
Class<?> actualType = ClassUtils.forName(queryClassName, classLoader);
if (actualType.isArray()) {
actualType = actualType.getComponentType();
}
if (ClassUtils.isAssignable(entityPathType, actualType)) {
logger.debug("Registering Q type %s for %s.");
context.getRuntimeHints().reflection().registerType(TypeReference.of(queryClassName),
@ -84,7 +86,10 @@ public class QTypeContributor { @@ -84,7 +86,10 @@ public class QTypeContributor {
private static String getQueryClassName(Class<?> domainClass) {
String simpleClassName = ClassUtils.getShortName(domainClass);
String pkgName = domainClass.getPackage().getName();
String pkgName = domainClass.getPackageName();
if (ObjectUtils.isEmpty(pkgName)) {
return String.format("Q%s%s", getClassBase(simpleClassName), domainClass.getSimpleName());
}
return String.format("%s.Q%s%s", pkgName, getClassBase(simpleClassName), domainClass.getSimpleName());
}

23
src/test/java/QTypeInDefaultPackage.java

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
/*
* Copyright 2025 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.
*/
/**
* Dummy type looking like a QueryDSL Generated one but its not - does not extend the
* {@link com.querydsl.core.types.dsl.EntityPathBase})
*
* @author Christoph Strobl
*/
public class QTypeInDefaultPackage {}

62
src/test/java/org/springframework/data/util/QTypeContributorUnitTests.java

@ -15,7 +15,12 @@ @@ -15,7 +15,12 @@
*/
package org.springframework.data.util;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.ClassNameGenerator;
@ -26,7 +31,6 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; @@ -26,7 +31,6 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.data.aot.sample.ConfigWithQuerydslPredicateExecutor.Person;
import org.springframework.data.aot.sample.QConfigWithQuerydslPredicateExecutor_Person;
import org.springframework.data.classloadersupport.HidingClassLoader;
import org.springframework.data.querydsl.User;
import org.springframework.javapoet.ClassName;
import com.querydsl.core.types.EntityPath;
@ -34,6 +38,7 @@ import com.querydsl.core.types.EntityPath; @@ -34,6 +38,7 @@ import com.querydsl.core.types.EntityPath;
/**
* Unit tests for {@link QTypeContributor}.
*
* @author Christoph Strobl
* @author ckdgus08
*/
class QTypeContributorUnitTests {
@ -75,8 +80,8 @@ class QTypeContributorUnitTests { @@ -75,8 +80,8 @@ class QTypeContributorUnitTests {
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
}
@Test // DATAMONGO-4958
void doesNotAddQTypeHintForArrayType() {
@Test // GH-3284
void addsQTypeHintForArrayType() {
GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
@ -85,48 +90,47 @@ class QTypeContributorUnitTests { @@ -85,48 +90,47 @@ class QTypeContributorUnitTests {
assertThat(generationContext.getRuntimeHints()).matches(
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person.class).negate());
assertThat(generationContext.getRuntimeHints()).matches(
RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class).negate());
assertThat(generationContext.getRuntimeHints())
.matches(RuntimeHintsPredicates.reflection().onType(QConfigWithQuerydslPredicateExecutor_Person[].class));
}
@Test // DATAMONGO-4958
void addsQTypeHintForQUserType() {
@Test // GH-3284
void doesNotAddQTypeHintForPrimitiveType() {
GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
QTypeContributor.contributeEntityPath(User.class, generationContext, getClass().getClassLoader());
QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader());
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints()
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
.count();
assertThat(qUserHintCount).isEqualTo(1);
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
}
@Test // DATAMONGO-4958
void doesNotAddQTypeHintForQUserArrayType() {
@Test // GH-3284
void doesNotFailForTypeInDefaultPackage() throws Exception {
GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
var classLoader = getClass().getClassLoader();
QTypeContributor.contributeEntityPath(User[].class, generationContext, classLoader);
class CapturingClassLoader extends ClassLoader {
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
var qUserHintCount = generationContext.getRuntimeHints().reflection().typeHints()
.filter(hint -> hint.getType().getName().equals("org.springframework.data.querydsl.QUser"))
.count();
assertThat(qUserHintCount).isEqualTo(0);
}
final Set<String> lookups = new HashSet<>(10);
@Test // DATAMONGO-4958
void doesNotAddQTypeHintForPrimitiveType() {
CapturingClassLoader() {
super(URLClassLoader.getSystemClassLoader());
}
GenerationContext generationContext = new DefaultGenerationContext(
new ClassNameGenerator(ClassName.get(this.getClass())), new InMemoryGeneratedFiles());
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
lookups.add(name);
return super.loadClass(name);
}
}
QTypeContributor.contributeEntityPath(int.class, generationContext, getClass().getClassLoader());
CapturingClassLoader classLoaderToUse = new CapturingClassLoader();
assertThat(generationContext.getRuntimeHints().reflection().typeHints()).isEmpty();
var typeInDefaultPackage = Class.forName("TypeInDefaultPackage");
assertThatNoException().isThrownBy(
() -> QTypeContributor.contributeEntityPath(typeInDefaultPackage, generationContext, classLoaderToUse));
assertThat(classLoaderToUse.lookups).contains("QTypeInDefaultPackage");
}
}

Loading…
Cancel
Save