1
1
package org .axonframework .intellij .ide .plugin .publisher ;
2
2
3
+ import static java .util .Arrays .asList ;
4
+
5
+ import java .util .Collections ;
6
+ import java .util .HashSet ;
7
+ import java .util .Set ;
8
+ import java .util .concurrent .ConcurrentHashMap ;
9
+
10
+ import org .axonframework .intellij .ide .plugin .handler .AnnotationTypes ;
11
+
12
+
3
13
import com .intellij .openapi .fileTypes .StdFileTypes ;
4
14
import com .intellij .openapi .project .Project ;
5
15
import com .intellij .openapi .util .Condition ;
6
- import com .intellij .psi .*;
16
+ import com .intellij .psi .JavaPsiFacade ;
17
+ import com .intellij .psi .PsiAnnotation ;
18
+ import com .intellij .psi .PsiClass ;
19
+ import com .intellij .psi .PsiElement ;
20
+ import com .intellij .psi .PsiMethod ;
21
+ import com .intellij .psi .PsiMethodCallExpression ;
22
+ import com .intellij .psi .PsiNewExpression ;
23
+ import com .intellij .psi .PsiParameter ;
24
+ import com .intellij .psi .PsiReference ;
25
+ import com .intellij .psi .PsiType ;
26
+ import com .intellij .psi .PsiTypeElement ;
7
27
import com .intellij .psi .search .GlobalSearchScope ;
8
28
import com .intellij .psi .search .searches .MethodReferencesSearch ;
9
29
import com .intellij .psi .search .searches .ReferencesSearch ;
10
30
import com .intellij .psi .util .PsiTreeUtil ;
11
31
import com .intellij .util .Processor ;
12
32
import com .intellij .util .Query ;
13
33
14
- import java .util .Collections ;
15
- import java .util .HashSet ;
16
- import java .util .Set ;
17
- import java .util .concurrent .ConcurrentHashMap ;
18
-
19
- import static java .util .Arrays .asList ;
20
-
21
34
class DefaultEventPublisherProvider implements PublisherProvider {
22
35
23
- private final ConcurrentHashMap <Project , Set <PsiMethod >> publisherMethodsPerProject = new ConcurrentHashMap <Project , Set <PsiMethod >>();
36
+ private final ConcurrentHashMap <Project , Set <PsiElement >> publisherMethodsPerProject = new ConcurrentHashMap <Project , Set <PsiElement >>();
24
37
25
38
@ Override
26
39
public void scanPublishers (final Project project , GlobalSearchScope scope , final Registrar registrar ) {
27
40
cleanClosedProjects ();
28
- publisherMethodsPerProject .putIfAbsent (project , new HashSet <PsiMethod >());
29
- Set <PsiMethod > psiMethods = publisherMethodsPerProject .get (project );
41
+ publisherMethodsPerProject .putIfAbsent (project , new HashSet <PsiElement >());
42
+ Set <PsiElement > psiMethods = publisherMethodsPerProject .get (project );
30
43
psiMethods .addAll (findMethods (project , GlobalSearchScope .allScope (project ),
31
44
"org.axonframework.eventsourcing.AbstractEventSourcedAggregateRoot" , "apply" ));
32
45
psiMethods .addAll (findMethods (project , GlobalSearchScope .allScope (project ),
@@ -51,7 +64,7 @@ public boolean process(PsiReference psiReference) {
51
64
PsiMethod method = (PsiMethod ) PsiTreeUtil .findFirstParent (psiReference .getElement (),
52
65
new IsMethodWithParameterCondition ());
53
66
if (methodHasParameter (method )) {
54
- PsiAnnotation methodAnnotation = method .getModifierList ().findAnnotation ("org.axonframework.commandhandling.annotation.CommandHandler" );
67
+ PsiAnnotation methodAnnotation = method .getModifierList ().findAnnotation (AnnotationTypes . COMMAND_EVENT_HANDLER . getFullyQualifiedName () );
55
68
PsiParameter firstCommandHandlerArgument = method .getParameterList ().getParameters ()[0 ];
56
69
if (methodIsAnnotatedAsCommandHandler (methodAnnotation )) {
57
70
PsiTypeElement firstCommandHandlerArgumentType = firstCommandHandlerArgument .getTypeElement ();
@@ -73,8 +86,10 @@ private boolean methodIsAnnotatedAsCommandHandler(PsiAnnotation methodCommandHan
73
86
74
87
private void findAndRegisterAllConstructors (PsiTypeElement firstCommandHandlerArgumentType ) {
75
88
final PsiType type = firstCommandHandlerArgumentType .getType ();
89
+ GlobalSearchScope scopeNarrowedToJavaSourceFiles =
90
+ GlobalSearchScope .getScopeRestrictedByFileTypes (GlobalSearchScope .allScope (project ), StdFileTypes .JAVA );
76
91
PsiClass parameterClass = JavaPsiFacade .getInstance (project )
77
- .findClass (type .getCanonicalText (), GlobalSearchScope . allScope ( project ) );
92
+ .findClass (type .getCanonicalText (), scopeNarrowedToJavaSourceFiles );
78
93
if (parameterClass != null ) {
79
94
PsiMethod [] constructors = parameterClass .getConstructors ();
80
95
if (parameterClassHasConstructor (constructors )) {
@@ -83,40 +98,44 @@ private void findAndRegisterAllConstructors(PsiTypeElement firstCommandHandlerAr
83
98
}
84
99
}
85
100
86
- private boolean parameterClassHasConstructor (PsiMethod [] constructors ) {
87
- return constructors .length > 0 ;
88
- }
89
-
90
101
private void registerAllConstructorInvocations (final PsiType type , PsiMethod [] constructors ) {
91
102
for (PsiMethod constructor : constructors ) {
92
103
Query <PsiReference > constructorCalls = MethodReferencesSearch .search (constructor );
93
104
constructorCalls .forEachAsync (new Processor <PsiReference >() {
94
105
@ Override
95
106
public boolean process (PsiReference psiReference ) {
96
- registrar .registerPublisher (new CommandEventPublisher (type , psiReference .getElement ()));
107
+ CommandEventPublisher eventPublisher = new CommandEventPublisher (type , psiReference .getElement ());
108
+ registrar .registerPublisher (eventPublisher );
109
+ Set <PsiElement > psiMethods = publisherMethodsPerProject .get (project );
110
+ psiMethods .add (psiReference .getElement ());
111
+
97
112
return true ;
98
113
}
99
114
});
100
115
}
101
116
}
102
-
103
- private boolean methodHasParameter (PsiMethod method ) {
104
- return method != null && method .getParameterList ().getParametersCount () > 0 ;
105
- }
106
117
});
107
118
}
108
119
}
109
120
121
+ private boolean parameterClassHasConstructor (PsiMethod [] constructors ) {
122
+ return constructors .length > 0 ;
123
+ }
124
+
125
+ private boolean methodHasParameter (PsiMethod method ) {
126
+ return method != null && method .getParameterList ().getParametersCount () > 0 ;
127
+ }
128
+
110
129
private PsiClass findCommandHandlersAnnotation (Project project ) {
111
130
return JavaPsiFacade .getInstance (project )
112
131
.findClass ("org.axonframework.commandhandling.annotation.CommandHandler" ,
113
132
GlobalSearchScope .allScope (project ));
114
133
}
115
134
116
135
private void scanEventPublishers (Project project , GlobalSearchScope scope , final Registrar registrar ) {
117
- for (final PsiMethod method : publisherMethodsPerProject .get (project )) {
136
+ for (final PsiElement method : publisherMethodsPerProject .get (project )) {
118
137
Query <PsiReference > invocations =
119
- MethodReferencesSearch .search (method , scope , false );
138
+ MethodReferencesSearch .search (( PsiMethod ) method , scope , false );
120
139
invocations .forEachAsync (new Processor <PsiReference >() {
121
140
@ Override
122
141
public boolean process (PsiReference psiReference ) {
@@ -166,14 +185,24 @@ private Set<PsiMethod> findMethods(Project project, GlobalSearchScope allScope,
166
185
public Publisher resolve (PsiElement element ) {
167
186
if (element instanceof PsiMethodCallExpression ) {
168
187
PsiMethodCallExpression expression = (PsiMethodCallExpression ) element ;
169
- PsiType [] expressionTypes = expression . getArgumentList (). getExpressionTypes ();
170
- for ( PsiMethod method : publisherMethodsPerProject . get ( element . getProject ())) {
171
- if (expression . getMethodExpression (). getReference () != null
188
+ for ( PsiElement method : publisherMethodsPerProject . get ( element . getProject ())) {
189
+ boolean hasReference = expression . getMethodExpression (). getReference () != null ;
190
+ if (hasReference
172
191
&& expression .getMethodExpression ().isReferenceTo (method )) {
192
+ PsiType [] expressionTypes = expression .getArgumentList ().getExpressionTypes ();
173
193
return new DefaultEventPublisher (expressionTypes [0 ], element );
174
194
}
175
195
}
176
196
}
197
+ if (element instanceof PsiNewExpression ) {
198
+ PsiNewExpression expression = (PsiNewExpression ) element ;
199
+
200
+ for (PsiElement classType : publisherMethodsPerProject .get (element .getProject ())) {
201
+ if (expression .getClassReference () != null && classType .isEquivalentTo (expression .getClassReference ())) {
202
+ return new CommandEventPublisher (expression .getType (), element );
203
+ }
204
+ }
205
+ }
177
206
return null ;
178
207
}
179
208
}
0 commit comments