Skip to content

Commit 4fcc7bf

Browse files
committed
GH-1633: refactored annotation storage inside of stereotype elements
1 parent 59d0a16 commit 4fcc7bf

File tree

11 files changed

+84
-60
lines changed

11 files changed

+84
-60
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public String getTypeLabel(StereotypeClassElement type) {
6161

6262
return modules.getModuleByType(type)
6363
.map(it -> it.getBasePackage())
64-
.map(it -> new StereotypePackageElement(it, Collections.emptyList()))
64+
.map(it -> new StereotypePackageElement(it, Collections.emptySet()))
6565
.map(it -> StructureViewUtil.abbreviate(it, type))
6666
.orElseGet(type::getType);
6767
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
package org.springframework.ide.vscode.boot.java.commands;
1212

1313
import java.util.Collection;
14-
import java.util.LinkedHashMap;
15-
import java.util.List;
1614
import java.util.Set;
1715
import java.util.TreeMap;
1816
import java.util.stream.Collectors;
@@ -61,7 +59,7 @@ private Collection<StereotypeClassElement> getClassElements(NamedInterface named
6159
private StereotypeClassElement findClassElement(String className, IJavaProject project, SpringMetamodelIndex springIndex) {
6260
return springIndex.getNodesOfType(project.getElementName(), StereotypeClassElement.class).stream()
6361
.filter(classElement -> classElement.getType().equals(className))
64-
.findAny().orElse(new StereotypeClassElement(className, null, Set.of(), List.of()));
62+
.findAny().orElse(new StereotypeClassElement(className, null, Set.of(), Set.of()));
6563
}
6664

6765
private Collection<StereotypeClassElement> getInternalTypes(ApplicationModule module) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public static StereotypePackageElement identifyMainApplicationPackage(IJavaProje
111111
List<StereotypeClassElement> classNodes = springIndex.getNodesOfType(project.getElementName(), StereotypeClassElement.class);
112112

113113
Optional<StereotypePackageElement> packageElement = classNodes.stream()
114-
.filter(node -> node.getAnnotationTypes().contains(Annotations.BOOT_APP))
114+
.filter(node -> node.isAnnotatedWith(Annotations.BOOT_APP))
115115
.map(node -> getPackage(node.getType()))
116116
.map(packageName -> findPackageNode(packageName, project, springIndex))
117117
.findFirst();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom, Inc.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom, Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.ide.vscode.boot.java.stereotypes;
12+
13+
import java.util.Set;
14+
15+
import org.springframework.ide.vscode.commons.protocol.spring.AbstractSpringIndexElement;
16+
17+
public abstract class AbstractStereotypeIndexElement extends AbstractSpringIndexElement implements StereotypeAnnotatedElement {
18+
19+
private Set<String> annotationTypes;
20+
21+
public AbstractStereotypeIndexElement(Set<String> annotationTypes) {
22+
this.annotationTypes = annotationTypes;
23+
}
24+
25+
@Override
26+
public Set<String> getAnnotationTypes() {
27+
return annotationTypes;
28+
}
29+
30+
@Override
31+
public boolean isAnnotatedWith(String annotationType) {
32+
return annotationTypes.contains(annotationType);
33+
}
34+
35+
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,7 @@ private Collection<Stereotype> fromTypeInternal(StereotypeClassElement type, Ana
117117
}
118118

119119
private static boolean isAnnotated(StereotypeAnnotatedElement element, String fqn) {
120-
return element.getAnnotationTypes().stream()
121-
.filter(it -> !it.startsWith("java"))
122-
.anyMatch(it -> it.equals(fqn) /* || isAnnotated(it, fqn)*/ );
120+
return element.isAnnotatedWith(fqn);
123121
}
124122

125123
private static boolean doesImplement(StereotypeClassElement type, String fqn) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.stereotypes;
1212

13-
import java.util.List;
13+
import java.util.Set;
1414

1515
public interface StereotypeAnnotatedElement {
1616

17-
public List<String> getAnnotationTypes();
17+
public Set<String> getAnnotationTypes();
18+
public boolean isAnnotatedWith(String annotationType);
1819

1920
}

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,18 @@
1515

1616
import org.eclipse.lsp4j.Location;
1717
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
18-
import org.springframework.ide.vscode.commons.protocol.spring.AbstractSpringIndexElement;
1918

20-
public class StereotypeClassElement extends AbstractSpringIndexElement implements StereotypeAnnotatedElement {
19+
public class StereotypeClassElement extends AbstractStereotypeIndexElement {
2120

2221
private final String type;
2322
private final Location location;
24-
2523
private final Set<String> supertypes;
26-
private List<String> annotationTypes;
2724

28-
public StereotypeClassElement(String type, Location location, Set<String> supertypes, List<String> annotationTypes) {
25+
public StereotypeClassElement(String type, Location location, Set<String> supertypes, Set<String> annotationTypes) {
26+
super(annotationTypes);
2927
this.type = type;
3028
this.location = location;
3129
this.supertypes = supertypes;
32-
this.annotationTypes = annotationTypes;
3330
}
3431

3532
public String getType() {
@@ -49,11 +46,6 @@ public boolean doesImplement(String fqn) {
4946
return supertypes.contains(fqn);
5047
}
5148

52-
@Override
53-
public List<String> getAnnotationTypes() {
54-
return annotationTypes;
55-
}
56-
5749
public List<StereotypeMethodElement> getMethods() {
5850
return SpringMetamodelIndex.getNodesOfType(StereotypeMethodElement.class, List.of(this));
5951
}

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,24 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.stereotypes;
1212

13-
import java.util.List;
13+
import java.util.Set;
1414

1515
import org.eclipse.lsp4j.Location;
16-
import org.springframework.ide.vscode.commons.protocol.spring.AbstractSpringIndexElement;
1716

18-
public class StereotypeMethodElement extends AbstractSpringIndexElement implements StereotypeAnnotatedElement {
17+
public class StereotypeMethodElement extends AbstractStereotypeIndexElement {
1918

2019
private final String methodName;
2120
private final String methodLabel;
2221
private final String methodSignature;
2322

2423
private final Location location;
25-
private List<String> annotationTypes;
2624

27-
public StereotypeMethodElement(String methodName, String methodLabel, String methodSignature, Location location, List<String> annotationTypes) {
25+
public StereotypeMethodElement(String methodName, String methodLabel, String methodSignature, Location location, Set<String> annotationTypes) {
26+
super(annotationTypes);
2827
this.methodName = methodName;
2928
this.methodLabel = methodLabel;
3029
this.methodSignature = methodSignature;
3130
this.location = location;
32-
this.annotationTypes = annotationTypes;
3331
}
3432

3533
public String getMethodName() {
@@ -48,8 +46,4 @@ public Location getLocation() {
4846
return location;
4947
}
5048

51-
public List<String> getAnnotationTypes() {
52-
return annotationTypes;
53-
}
54-
5549
}

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

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,21 @@
1010
*******************************************************************************/
1111
package org.springframework.ide.vscode.boot.java.stereotypes;
1212

13-
import java.util.List;
13+
import java.util.Set;
1414

15-
import org.springframework.ide.vscode.commons.protocol.spring.AbstractSpringIndexElement;
16-
17-
public class StereotypePackageElement extends AbstractSpringIndexElement implements StereotypeAnnotatedElement {
15+
public class StereotypePackageElement extends AbstractStereotypeIndexElement {
1816

1917
private final String packageName;
2018
private final boolean isMainPackage;
21-
private final List<String> annotationTypes;
2219

23-
public StereotypePackageElement(String packageName, List<String> annotationTypes) {
20+
public StereotypePackageElement(String packageName, Set<String> annotationTypes) {
2421
this(packageName, annotationTypes, false);
2522
}
2623

27-
public StereotypePackageElement(String packageName, List<String> annotationTypes, boolean isMainPackage) {
24+
public StereotypePackageElement(String packageName, Set<String> annotationTypes, boolean isMainPackage) {
25+
super(annotationTypes);
2826
this.packageName = packageName;
2927
this.isMainPackage = isMainPackage;
30-
this.annotationTypes = annotationTypes;
3128
}
3229

3330
public String getPackageName() {
@@ -38,8 +35,4 @@ public boolean isMainPackage() {
3835
return isMainPackage;
3936
}
4037

41-
public List<String> getAnnotationTypes() {
42-
return annotationTypes;
43-
}
44-
45-
}
38+
}

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
import java.util.Arrays;
1515
import java.util.Collection;
1616
import java.util.Iterator;
17+
import java.util.LinkedHashSet;
1718
import java.util.List;
1819
import java.util.Optional;
1920
import java.util.Set;
21+
import java.util.stream.Collectors;
2022
import java.util.stream.Stream;
2123

2224
import org.eclipse.jdt.core.dom.ASTNode;
@@ -108,11 +110,11 @@ private void createStereotypeElementForPackage(PackageDeclaration packageDeclara
108110
@SuppressWarnings("unchecked")
109111
List<Annotation> annotations = packageDeclaration.annotations();
110112

111-
List<String> annotationTypes = annotations.stream()
113+
Set<String> annotationTypes = annotations.stream()
112114
.map(annotation -> annotation.resolveAnnotationBinding())
113115
.filter(binding -> binding != null)
114116
.map(binding -> binding.getAnnotationType().getQualifiedName())
115-
.toList();
117+
.collect(Collectors.toCollection(LinkedHashSet<String>::new));
116118

117119
StereotypePackageElement packageElement = new StereotypePackageElement(packageBinding.getName(), annotationTypes);
118120
context.getBeans().add(new CachedBean(context.getDocURI(), packageElement));
@@ -154,7 +156,7 @@ private void createStereotypeElementForType(AbstractTypeDeclaration typeDeclarat
154156
}
155157

156158
Collection<Annotation> annotations = ASTUtils.getAnnotations(typeDeclaration);
157-
List<String> annotationTypes = getAnnotationTypes(annotationHierarchies, superTypeAnnotations, annotations);
159+
Set<String> annotationTypes = getAnnotationTypes(annotationHierarchies, superTypeAnnotations, annotations);
158160

159161
SimpleName astNodeForLocation = typeDeclaration.getName();
160162
Location location = new Location(doc.getUri(), doc.toRange(astNodeForLocation.getStartPosition(), astNodeForLocation.getLength()));
@@ -184,7 +186,7 @@ else if (typeDeclaration instanceof RecordDeclaration) {
184186
String methodName = method.getName().getFullyQualifiedName();
185187

186188
Collection<Annotation> annotations = ASTUtils.getAnnotations(method);
187-
List<String> annotationTypes = getAnnotationTypes(annotationHierarchies, List.of(), annotations);
189+
Set<String> annotationTypes = getAnnotationTypes(annotationHierarchies, List.of(), annotations);
188190

189191
if (annotationTypes.size() > 0) { // only index annotated methods to avoid creating all those useless index elements for each and every method
190192
SimpleName astNodeForLocation = method.getName();
@@ -199,18 +201,18 @@ else if (typeDeclaration instanceof RecordDeclaration) {
199201
}
200202
}
201203

202-
private List<String> getAnnotationTypes(AnnotationHierarchies annotationHierarchies,
204+
private Set<String> getAnnotationTypes(AnnotationHierarchies annotationHierarchies,
203205
List<IAnnotationBinding> superTypeAnnotations, Collection<Annotation> annotations) {
204206
Stream<IAnnotationBinding> annotationBindings = annotations.stream()
205207
.map(annotation -> annotation.resolveAnnotationBinding())
206208
.filter(binding -> binding != null)
207209
.flatMap(binding -> Stream.concat(Stream.of(binding), getMetaAnnotations(annotationHierarchies, binding).stream()))
208210
.filter(binding -> !binding.getAnnotationType().getQualifiedName().startsWith("java"));
209211

210-
List<String> annotationTypes = Streams.concat(annotationBindings, superTypeAnnotations.stream())
212+
Set<String> annotationTypes = Streams.concat(annotationBindings, superTypeAnnotations.stream())
211213
.distinct()
212214
.map(binding -> binding.getAnnotationType().getQualifiedName())
213-
.toList();
215+
.collect(Collectors.toCollection(LinkedHashSet<String>::new));
214216

215217
return annotationTypes;
216218
}

0 commit comments

Comments
 (0)