Skip to content

Commit

Permalink
#10 - Searching in hierarchical data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
biagio committed Dec 20, 2024
1 parent a4fc86d commit a71647b
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 42 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ curl -X POST -H "Content-type: application/json" -d '{
<dependency>
<groupId>app.tozzi</groupId>
<artifactId>jpa-search-helper</artifactId>
<version>3.3.0</version>
<version>3.3.1</version>
</dependency>
```

#### Gradle
```
implementation 'app.tozzi:jpa-search-helper:3.3.0
implementation 'app.tozzi:jpa-search-helper:3.3.1
```

## Queries - Usage
Expand Down
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
plugins {
id 'java-library'
id 'maven-publish'
id 'org.springframework.boot' version '3.4.0'
id 'io.spring.dependency-management' version '1.1.6'
id 'org.springframework.boot' version '3.4.1'
id 'io.spring.dependency-management' version '1.1.7'
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
}

group = 'app.tozzi'
version = '3.3.0'
version = '3.3.1'

compileJava {
sourceCompatibility = JavaVersion.VERSION_17
Expand Down Expand Up @@ -65,7 +65,7 @@ publishing {
maven(MavenPublication) {
group = 'app.tozzi'
artifactId = 'jpa-search-helper'
version = "3.3.0"
version = "3.3.1"
from components.java
pom {
name = 'JPA Search Helper'
Expand Down
11 changes: 6 additions & 5 deletions src/main/java/app/tozzi/util/ReflectionUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static Map<String, Pair<Searchable, Field>> getAllSearchableFields(Class<

return SEARCHABLE_CACHE.computeIfAbsent(beanClass, key -> {
Map<String, Pair<Searchable, Field>> res = new HashMap<>();
getFields(new StringBuilder(), beanClass, Searchable.class, NestedSearchable.class, res);
getFields(new StringBuilder(), beanClass, Searchable.class, NestedSearchable.class, res, true);
return res;
});

Expand All @@ -65,13 +65,13 @@ public static Map<String, Pair<Projectable, Field>> getAllProjectableFields(Clas

return PROJECTABLE_CACHE.computeIfAbsent(beanClass, key -> {
Map<String, Pair<Projectable, Field>> res = new HashMap<>();
getFields(new StringBuilder(), beanClass, Projectable.class, NestedProjectable.class, res);
getFields(new StringBuilder(), beanClass, Projectable.class, NestedProjectable.class, res, true);
return res;
});

}

private static <A extends Annotation, N extends Annotation> void getFields(final StringBuilder root, Class<?> beanClass, Class<A> annotationClass, Class<N> nestedAnnotationClass, Map<String, Pair<A, Field>> res) {
private static <A extends Annotation, N extends Annotation> void getFields(final StringBuilder root, Class<?> beanClass, Class<A> annotationClass, Class<N> nestedAnnotationClass, Map<String, Pair<A, Field>> res, boolean evaluateNested) {

Stream.of(BeanUtils.getPropertyDescriptors(beanClass)).flatMap(pd -> Stream.of(pd.getReadMethod().getDeclaringClass().getDeclaredFields()))
.forEach(f -> {
Expand All @@ -80,12 +80,13 @@ private static <A extends Annotation, N extends Annotation> void getFields(final
res.putIfAbsent(root.isEmpty() ? f.getName() : root + "." + f.getName(), Pair.of(f.getAnnotation(annotationClass), f));
}

if (f.isAnnotationPresent(nestedAnnotationClass)) {
if (evaluateNested && f.isAnnotationPresent(nestedAnnotationClass)) {
if (!root.isEmpty()) {
root.append(".");
}
root.append(f.getName());
getFields(root, getType(f), annotationClass, nestedAnnotationClass, res);
var type = getType(f);
getFields(root, type, annotationClass, nestedAnnotationClass, res, !type.equals(beanClass));

if (root.indexOf(".") != -1) {
root.delete(root.lastIndexOf("."), root.length());
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/app/tozzi/model/RecursiveModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package app.tozzi.model;

import app.tozzi.annotation.NestedSearchable;
import app.tozzi.annotation.Searchable;
import lombok.Data;

@Data
public class RecursiveModel {

private Long id;

@Searchable
private String name;

@NestedSearchable
private RecursiveModel predecessor;

@NestedSearchable
private MyModel myModel;
}
41 changes: 10 additions & 31 deletions src/test/java/app/tozzi/util/ReflectionUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import app.tozzi.model.JPASearchOperatorFilter;
import app.tozzi.model.JPASearchType;
import app.tozzi.model.MyModel;
import app.tozzi.model.RecursiveModel;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
Expand All @@ -14,37 +15,6 @@

public class ReflectionUtilsTest {

// @Test
// public void getIdFields() {
// var map = ReflectionUtils.getIdFields(MyEntity.class);
// assertNotNull(map);
// assertEquals(1, map.size());
// assertTrue(map.containsKey("id"));
// assertEquals(Long.class, map.get("id").getType());
// }
//
// @Test
// public void getIdFields_embedded() {
// var map = ReflectionUtils.getIdFields(MyEntity2.class);
// assertNotNull(map);
// assertEquals(2, map.size());
// assertTrue(map.containsKey("embeddedID.testId1"));
// assertTrue(map.containsKey("embeddedID.testId2"));
// assertEquals(String.class, map.get("embeddedID.testId1").getType());
// assertEquals(String.class, map.get("embeddedID.testId2").getType());
// }
//
// @Test
// public void getIdFields_idClass() {
// var map = ReflectionUtils.getIdFields(MyEntity3.class);
// assertNotNull(map);
// assertEquals(2, map.size());
// assertTrue(map.containsKey("testID1"));
// assertTrue(map.containsKey("testID2"));
// assertEquals(String.class, map.get("testID1").getType());
// assertEquals(String.class, map.get("testID2").getType());
// }

@Test
public void getAllProjectableFields() {
var projectableFields = ReflectionUtils.getAllProjectableFields(MyModel.class);
Expand Down Expand Up @@ -94,4 +64,13 @@ public void getAllSearchableFields() {
assertFalse(searchableFields.containsKey("mySubModel.mySubSubModel"));
assertFalse(searchableFields.containsKey("mySubModel.mySubSubModel.notSearchableNo"));
}

@Test
public void recursiveModelTest() {
var map = ReflectionUtils.getAllSearchableFields(RecursiveModel.class);
assertNotNull(map);
assertTrue(map.containsKey("name"));
assertTrue(map.containsKey("predecessor.name"));
assertEquals(30, map.size());
}
}

0 comments on commit a71647b

Please sign in to comment.