1313import java .util .Arrays ;
1414import java .util .Collection ;
1515import java .util .HashSet ;
16+ import java .util .List ;
17+ import java .util .Optional ;
1618import java .util .Set ;
1719import java .util .stream .Collectors ;
1820import java .util .stream .Stream ;
1921
22+ import org .eclipse .jdt .core .dom .ASTVisitor ;
2023import org .eclipse .jdt .core .dom .Annotation ;
24+ import org .eclipse .jdt .core .dom .Expression ;
2125import org .eclipse .jdt .core .dom .IMethodBinding ;
2226import org .eclipse .jdt .core .dom .ITypeBinding ;
2327import org .eclipse .jdt .core .dom .MethodDeclaration ;
28+ import org .eclipse .jdt .core .dom .MethodInvocation ;
2429import org .eclipse .jdt .core .dom .TypeDeclaration ;
2530import org .eclipse .lsp4j .Location ;
2631import org .eclipse .lsp4j .SymbolKind ;
3035import org .slf4j .LoggerFactory ;
3136import org .springframework .ide .vscode .boot .java .Annotations ;
3237import org .springframework .ide .vscode .boot .java .events .EventListenerIndexElement ;
38+ import org .springframework .ide .vscode .boot .java .events .EventPublisherIndexElement ;
3339import org .springframework .ide .vscode .boot .java .handlers .AbstractSymbolProvider ;
3440import org .springframework .ide .vscode .boot .java .handlers .EnhancedSymbolInformation ;
3541import org .springframework .ide .vscode .boot .java .utils .ASTUtils ;
@@ -130,10 +136,65 @@ protected void createSymbol(Annotation node, ITypeBinding annotationType, Collec
130136 }
131137 }
132138 }
139+
140+ // event publisher checks
141+ for (InjectionPoint injectionPoint : injectionPoints ) {
142+ if (Annotations .EVENT_PUBLISHER .equals (injectionPoint .getType ())) {
143+ context .getNextPassFiles ().add (context .getFile ());
144+ }
145+ }
133146
134147 context .getGeneratedSymbols ().add (new CachedSymbol (context .getDocURI (), context .getLastModified (), new EnhancedSymbolInformation (symbol )));
135148 context .getBeans ().add (new CachedBean (context .getDocURI (), beanDefinition ));
136149 }
150+
151+ @ Override
152+ protected void addSymbolsPass2 (Annotation node , ITypeBinding annotationType , Collection <ITypeBinding > metaAnnotations , SpringIndexerJavaContext context , TextDocument doc ) {
153+ TypeDeclaration type = (TypeDeclaration ) node .getParent ();
154+ type .accept (new ASTVisitor () {
155+
156+ @ Override
157+ public boolean visit (MethodInvocation methodInvocation ) {
158+ try {
159+ String methodName = methodInvocation .getName ().toString ();
160+ if ("publishEvent" .equals (methodName )) {
161+
162+ IMethodBinding methodBinding = methodInvocation .resolveMethodBinding ();
163+ boolean doesInvokeEventPublisher = Annotations .EVENT_PUBLISHER .equals (methodBinding .getDeclaringClass ().getQualifiedName ());
164+ if (doesInvokeEventPublisher ) {
165+ List <?> arguments = methodInvocation .arguments ();
166+ if (arguments != null && arguments .size () == 1 ) {
167+
168+ ITypeBinding eventTypeBinding = ((Expression ) arguments .get (0 )).resolveTypeBinding ();
169+ if (eventTypeBinding != null ) {
170+
171+ DocumentRegion nodeRegion = ASTUtils .nodeRegion (doc , methodInvocation );
172+ Location location ;
173+ location = new Location (doc .getUri (), nodeRegion .asRange ());
174+
175+ EventPublisherIndexElement eventPublisherIndexElement = new EventPublisherIndexElement (eventTypeBinding .getQualifiedName (), location );
176+ Bean publisherBeanElement = findBean (node , methodInvocation , context , doc );
177+ if (publisherBeanElement != null ) {
178+ publisherBeanElement .addChild (eventPublisherIndexElement );
179+ }
180+
181+ // symbol
182+ String symbolLabel = "@EventPublisher (" + eventTypeBinding .getName () + ")" ;
183+ WorkspaceSymbol symbol = new WorkspaceSymbol (symbolLabel , SymbolKind .Interface , Either .forLeft (location ));
184+ EnhancedSymbolInformation enhancedSymbol = new EnhancedSymbolInformation (symbol );
185+ context .getGeneratedSymbols ().add (new CachedSymbol (context .getDocURI (), context .getLastModified (), enhancedSymbol ));
186+ }
187+ }
188+ }
189+ }
190+
191+ } catch (BadLocationException e ) {
192+ log .error ("" , e );
193+ }
194+ return super .visit (methodInvocation );
195+ }
196+ });
197+ }
137198
138199 private MethodDeclaration findHandleEventMethod (TypeDeclaration type ) {
139200 MethodDeclaration [] methods = type .getMethods ();
@@ -148,6 +209,24 @@ private MethodDeclaration findHandleEventMethod(TypeDeclaration type) {
148209 }
149210 return null ;
150211 }
212+
213+ private Bean findBean (Annotation annotation , MethodInvocation methodInvocation , SpringIndexerJavaContext context , TextDocument doc ) {
214+ TypeDeclaration declaringType = ASTUtils .findDeclaringType (methodInvocation );
215+ if (declaringType != null ) {
216+ String beanName = BeanUtils .getBeanNameFromComponentAnnotation (annotation , declaringType );
217+ if (beanName != null ) {
218+ Optional <Bean > first = context .getBeans ().stream ().filter (cachedBean -> cachedBean .getDocURI ().equals (doc .getUri ()))
219+ .map (cachedBean -> cachedBean .getBean ())
220+ .filter (bean -> bean instanceof Bean )
221+ .map (bean -> (Bean ) bean )
222+ .filter (bean -> bean .getName ().equals (beanName ))
223+ .findFirst ();
224+ return first .get ();
225+ }
226+ }
227+
228+ return null ;
229+ }
151230
152231 protected String beanLabel (String searchPrefix , String annotationTypeName , Collection <String > metaAnnotationNames , String beanName , String beanType ) {
153232 StringBuilder symbolLabel = new StringBuilder ();
0 commit comments