Skip to content

Commit e586ebd

Browse files
committed
GH-1491: minor refactorings and preparing case for query methods from type hierarchy
1 parent d2b8cdb commit e586ebd

File tree

3 files changed

+70
-9
lines changed

3 files changed

+70
-9
lines changed

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/data/DataRepositorySymbolProvider.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,21 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.data;
1212

13+
import java.util.ArrayList;
1314
import java.util.Collection;
1415
import java.util.HashSet;
16+
import java.util.List;
1517
import java.util.Set;
1618

1719
import org.eclipse.jdt.core.dom.Annotation;
20+
import org.eclipse.jdt.core.dom.IMethodBinding;
1821
import org.eclipse.jdt.core.dom.ITypeBinding;
1922
import org.eclipse.jdt.core.dom.MethodDeclaration;
2023
import org.eclipse.jdt.core.dom.Modifier;
2124
import org.eclipse.jdt.core.dom.NormalAnnotation;
2225
import org.eclipse.jdt.core.dom.SimpleName;
2326
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
27+
import org.eclipse.jdt.core.dom.Type;
2428
import org.eclipse.jdt.core.dom.TypeDeclaration;
2529
import org.eclipse.lsp4j.Location;
2630
import org.eclipse.lsp4j.Range;
@@ -99,22 +103,22 @@ public void addSymbols(TypeDeclaration typeDeclaration, SpringIndexerJavaContext
99103
}
100104

101105
private void indexQueryMethods(Bean beanDefinition, TypeDeclaration typeDeclaration, SpringIndexerJavaContext context, TextDocument doc) {
102-
MethodDeclaration[] methods = typeDeclaration.getMethods();
103-
if (methods == null) return;
106+
AnnotationHierarchies annotationHierarchies = AnnotationHierarchies.get(typeDeclaration);
107+
108+
List<MethodDeclaration> methods = identifyQueryMethods(typeDeclaration, annotationHierarchies);
104109

105110
for (MethodDeclaration method : methods) {
106-
int modifiers = method.getModifiers();
107111
SimpleName nameNode = method.getName();
108112

109-
if (nameNode != null && (modifiers & Modifier.DEFAULT) == 0) {
113+
if (nameNode != null) {
110114
String methodName = nameNode.getFullyQualifiedName();
111115
DocumentRegion nodeRegion = ASTUtils.nodeRegion(doc, method);
112116

113117
try {
114118
Range range = doc.toRange(nodeRegion);
115119

116120
if (methodName != null) {
117-
String queryString = identifyQueryString(method);
121+
String queryString = identifyQueryString(method, annotationHierarchies);
118122
beanDefinition.addChild(new QueryMethodIndexElement(methodName, queryString, range));
119123
}
120124

@@ -125,8 +129,24 @@ private void indexQueryMethods(Bean beanDefinition, TypeDeclaration typeDeclarat
125129
}
126130
}
127131

128-
private String identifyQueryString(MethodDeclaration method) {
129-
AnnotationHierarchies annotationHierarchies = AnnotationHierarchies.get(method);
132+
private List<MethodDeclaration> identifyQueryMethods(TypeDeclaration type, AnnotationHierarchies annotationHierarchies) {
133+
List<MethodDeclaration> result = new ArrayList<>();
134+
135+
MethodDeclaration[] methods = type.getMethods();
136+
if (methods == null) return result;
137+
138+
for (MethodDeclaration method : methods) {
139+
int modifiers = method.getModifiers();
140+
141+
if ((modifiers & Modifier.DEFAULT) == 0) {
142+
result.add(method);
143+
}
144+
}
145+
146+
return result;
147+
}
148+
149+
private String identifyQueryString(MethodDeclaration method, AnnotationHierarchies annotationHierarchies) {
130150

131151
EmbeddedQueryExpression queryExpression = null;
132152

@@ -150,7 +170,7 @@ else if (annotation instanceof NormalAnnotation) {
150170

151171
return null;
152172
}
153-
173+
154174
protected String beanLabel(boolean isFunctionBean, String beanName, String beanType, String markerString) {
155175
StringBuilder symbolLabel = new StringBuilder();
156176
symbolLabel.append("@+");

headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/java/data/test/DataRepositoryIndexElementsTest.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.data.test;
1212

13+
import static org.junit.Assert.assertNull;
1314
import static org.junit.jupiter.api.Assertions.assertEquals;
1415

1516
import java.io.File;
@@ -20,6 +21,7 @@
2021
import org.apache.commons.lang3.ArrayUtils;
2122
import org.eclipse.lsp4j.TextDocumentIdentifier;
2223
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.Disabled;
2325
import org.junit.jupiter.api.Test;
2426
import org.junit.jupiter.api.extension.ExtendWith;
2527
import org.springframework.beans.factory.annotation.Autowired;
@@ -82,7 +84,7 @@ void testSimpleRepositoryElements() throws Exception {
8284
assertEquals("org.test.CustomerRepository", repoBean[0].getType());
8385

8486
Bean[] matchingBeans = springIndex.getMatchingBeans("test-spring-data-symbols", "org.springframework.data.repository.CrudRepository");
85-
assertEquals(3, matchingBeans.length);
87+
assertEquals(4, matchingBeans.length);
8688
ArrayUtils.contains(matchingBeans, repoBean[0]);
8789
}
8890

@@ -115,7 +117,35 @@ void testQueryMethodElementWithQueryString() throws Exception {
115117
QueryMethodIndexElement queryMethod = (QueryMethodIndexElement) queryMethods.get(0);
116118
assertEquals("findPetTypes", queryMethod.getMethodName());
117119
assertEquals("SELECT ptype FROM PetType ptype ORDER BY ptype.name", queryMethod.getQueryString());
120+
}
121+
122+
@Test
123+
void testNoRepositoryBeanAnnotationResultsInNoBeanIndexElement() throws Exception {
124+
String docUri = directory.toPath().resolve("src/main/java/org/test/CustomerRepositoryParentInterface.java").toUri().toString();
125+
126+
DocumentElement document = springIndex.getDocument(docUri);
127+
assertNull(document); // nothing in the doc, therefore not even the doc node is around
128+
}
129+
130+
@Test
131+
@Disabled // query methods from superclasses or interfaces not yet implemented, maybe requires a different way to think about this (separate index elements instead of one element with all query methods)
132+
void testQueryMethodsFromParentInterfaces() throws Exception {
133+
String docUri = directory.toPath().resolve("src/main/java/org/test/CustomerRepositoryWithParentInterfaces.java").toUri().toString();
134+
135+
DocumentElement document = springIndex.getDocument(docUri);
136+
List<SpringIndexElement> children = document.getChildren();
137+
Bean repositoryElement = (Bean) children.get(0);
138+
139+
List<SpringIndexElement> queryMethods = repositoryElement.getChildren();
140+
assertEquals(2, queryMethods.size());
141+
142+
QueryMethodIndexElement queryMethod = (QueryMethodIndexElement) queryMethods.get(0);
143+
assertEquals("findConcretePetTypes", queryMethod.getMethodName());
144+
assertEquals("CONCRETE REPO SELECT STATEMENT", queryMethod.getQueryString());
118145

146+
QueryMethodIndexElement parentQueryMethod = (QueryMethodIndexElement) queryMethods.get(1);
147+
assertEquals("findParentPetTypes", parentQueryMethod.getMethodName());
148+
assertEquals("PARENT REPO INTERFACE QUERY STATEMENT", parentQueryMethod.getQueryString());
119149
}
120150

121151
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.test;
2+
3+
import java.util.List;
4+
5+
import org.springframework.data.jpa.repository.Query;
6+
7+
public interface CustomerRepositoryWithParentInterfaces extends CustomerRepositoryParentInterface {
8+
9+
@Query("CONCRETE REPO SELECT STATEMENT")
10+
List<Object> findConcretePetTypes();
11+
}

0 commit comments

Comments
 (0)