10
10
*******************************************************************************/
11
11
package org .springframework .ide .vscode .boot .java .events ;
12
12
13
+ import java .util .Arrays ;
13
14
import java .util .List ;
15
+ import java .util .Map ;
14
16
import java .util .Optional ;
15
17
import java .util .Set ;
18
+ import java .util .stream .Collectors ;
16
19
17
20
import org .eclipse .jdt .core .dom .ASTNode ;
18
21
import org .eclipse .jdt .core .dom .Annotation ;
25
28
import org .springframework .ide .vscode .boot .index .SpringMetamodelIndex ;
26
29
import org .springframework .ide .vscode .boot .java .handlers .ReferenceProvider ;
27
30
import org .springframework .ide .vscode .commons .java .IJavaProject ;
31
+ import org .springframework .ide .vscode .commons .protocol .spring .AnnotationAttributeValue ;
32
+ import org .springframework .ide .vscode .commons .protocol .spring .AnnotationMetadata ;
28
33
import org .springframework .ide .vscode .commons .util .BadLocationException ;
29
34
import org .springframework .ide .vscode .commons .util .text .TextDocument ;
30
35
@@ -55,19 +60,26 @@ public List<? extends Location> provideReferences(CancelChecker cancelToken, IJa
55
60
List <EventListenerIndexElement > listeners = index .getNodesOfType (EventListenerIndexElement .class );
56
61
List <EventPublisherIndexElement > publishers = index .getNodesOfType (EventPublisherIndexElement .class );
57
62
58
- // when offset is inside an event listener, find the respective event type
59
- Optional <String > listenerEventType = listeners .stream ()
63
+ // when offset is inside an event listener, look for references from publishers
64
+ Optional <EventListenerIndexElement > listenerElement = listeners .stream ()
60
65
.filter (listener -> listener .getLocation ().getUri ().equals (doc .getUri ()))
61
66
.filter (eventListener -> isPositionInside (position , eventListener .getLocation ()))
62
- .map (eventListener -> eventListener .getEventType ())
63
67
.findAny ();
64
68
65
- if (listenerEventType .isPresent ()) {
66
- // use the listener event type to look for publishers for that type
67
- String eventType = listenerEventType .get ();
69
+ if (listenerElement .isPresent ()) {
70
+ Set <String > eventTypes = getListenerEventTypes (listenerElement .get ());
68
71
69
72
List <Location > foundLocations = publishers .stream ()
70
- .filter (publisher -> publisher .getEventType ().equals (eventType ) || publisher .getEventTypesFromHierarchy ().contains (eventType ))
73
+ .filter (publisher -> {
74
+ if (eventTypes .contains (publisher .getEventType ())) return true ;
75
+
76
+ for (String listenerEventType : eventTypes ) {
77
+ if (publisher .getEventTypesFromHierarchy ().contains (listenerEventType )) {
78
+ return true ;
79
+ }
80
+ }
81
+ return false ;
82
+ })
71
83
.map (publisher -> publisher .getLocation ())
72
84
.toList ();
73
85
@@ -76,20 +88,30 @@ public List<? extends Location> provideReferences(CancelChecker cancelToken, IJa
76
88
}
77
89
}
78
90
79
- // when offset is inside an event publisher, find the respective event type
91
+ // when offset is inside an event publisher, look for references from listeners
80
92
else {
81
93
Optional <EventPublisherIndexElement > publisherElement = publishers .stream ()
82
94
.filter (publisher -> publisher .getLocation ().getUri ().equals (doc .getUri ()))
83
95
.filter (eventPublisher -> isPositionInside (position , eventPublisher .getLocation ()))
84
96
.findAny ();
85
97
86
98
if (publisherElement .isPresent ()) {
87
- // use the publisher event type to look for listeners for that type
88
99
String eventType = publisherElement .get ().getEventType ();
89
100
Set <String > eventTypesFromHierarchy = publisherElement .get ().getEventTypesFromHierarchy ();
90
101
91
102
List <Location > foundLocations = listeners .stream ()
92
- .filter (listener -> listener .getEventType ().equals (eventType ) || eventTypesFromHierarchy .contains (listener .getEventType ()))
103
+ .filter (listener -> {
104
+ Set <String > listenerEventTypes = getListenerEventTypes (listener );
105
+ for (String listenerEventType : listenerEventTypes ) {
106
+ if (listenerEventType .equals (eventType )) {
107
+ return true ;
108
+ }
109
+ if (eventTypesFromHierarchy .contains (listenerEventType )) {
110
+ return true ;
111
+ }
112
+ }
113
+ return false ;
114
+ })
93
115
.map (listener -> listener .getLocation ())
94
116
.toList ();
95
117
@@ -106,6 +128,29 @@ public List<? extends Location> provideReferences(CancelChecker cancelToken, IJa
106
128
return null ;
107
129
}
108
130
131
+ private Set <String > getListenerEventTypes (EventListenerIndexElement eventListenerIndexElement ) {
132
+ AnnotationMetadata [] annotations = eventListenerIndexElement .getAnnotations ();
133
+ if (annotations != null && annotations .length > 0 ) {
134
+ for (AnnotationMetadata annotationMetadata : annotations ) {
135
+ Map <String , AnnotationAttributeValue []> attributes = annotationMetadata .getAttributes ();
136
+ if (attributes .containsKey ("classes" )) {
137
+ AnnotationAttributeValue [] annotationAttributeValues = attributes .get ("classes" );
138
+ return Arrays .stream (annotationAttributeValues )
139
+ .map (attributeValue -> attributeValue .getName ())
140
+ .collect (Collectors .toSet ());
141
+ }
142
+ else if (attributes .containsKey ("value" )) {
143
+ AnnotationAttributeValue [] annotationAttributeValues = attributes .get ("value" );
144
+ return Arrays .stream (annotationAttributeValues )
145
+ .map (attributeValue -> attributeValue .getName ())
146
+ .collect (Collectors .toSet ());
147
+ }
148
+ }
149
+ }
150
+
151
+ return Set .of (eventListenerIndexElement .getEventType ());
152
+ }
153
+
109
154
private boolean isPositionInside (Position position , Location location ) {
110
155
boolean afterStart = position .getLine () > location .getRange ().getStart ().getLine ()
111
156
|| (position .getLine () == location .getRange ().getStart ().getLine () && position .getCharacter () >= location .getRange ().getStart ().getCharacter ());
0 commit comments