Skip to content

Commit 0473ff1

Browse files
author
Rino
committed
IDEAPLUGIN-5 CommandPublisher links to CommandHandler
1 parent a142646 commit 0473ff1

File tree

2 files changed

+77
-44
lines changed

2 files changed

+77
-44
lines changed

src/main/java/org/axonframework/intellij/ide/plugin/annotator/AxonGutterAnnotator.java

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
package org.axonframework.intellij.ide.plugin.annotator;
22

3+
import javax.swing.Icon;
4+
5+
import java.util.ArrayList;
6+
import java.util.Collection;
7+
import java.util.Set;
8+
import java.util.TreeSet;
9+
10+
import org.axonframework.intellij.ide.plugin.handler.AnnotationTypes;
11+
import org.axonframework.intellij.ide.plugin.handler.Handler;
12+
import org.axonframework.intellij.ide.plugin.handler.HandlerProviderManager;
13+
import org.axonframework.intellij.ide.plugin.publisher.Publisher;
14+
import org.axonframework.intellij.ide.plugin.publisher.PublisherProviderManager;
15+
import org.jetbrains.annotations.NotNull;
16+
17+
318
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
419
import com.intellij.lang.annotation.Annotation;
520
import com.intellij.lang.annotation.AnnotationHolder;
@@ -10,19 +25,8 @@
1025
import com.intellij.psi.PsiElement;
1126
import com.intellij.psi.PsiIdentifier;
1227
import com.intellij.psi.PsiMethodCallExpression;
28+
import com.intellij.psi.PsiNewExpression;
1329
import com.intellij.psi.util.PsiTypesUtil;
14-
import org.axonframework.intellij.ide.plugin.handler.AnnotationTypes;
15-
import org.axonframework.intellij.ide.plugin.handler.Handler;
16-
import org.axonframework.intellij.ide.plugin.handler.HandlerProviderManager;
17-
import org.axonframework.intellij.ide.plugin.publisher.Publisher;
18-
import org.axonframework.intellij.ide.plugin.publisher.PublisherProviderManager;
19-
import org.jetbrains.annotations.NotNull;
20-
21-
import javax.swing.*;
22-
import java.util.ArrayList;
23-
import java.util.Collection;
24-
import java.util.Set;
25-
import java.util.TreeSet;
2630

2731
/**
2832
* This class shows an icon in the gutter when an Axon annotation is found. The icon can be used to navigate to all
@@ -40,7 +44,7 @@ public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolde
4044
if (element instanceof PsiClass) {
4145
tryAnnotateEventClass(holder, (PsiClass) element, publisherManager, handlerManager);
4246
tryAnnotateCommandClass(holder, (PsiClass) element, handlerManager);
43-
} else if ((element instanceof PsiMethodCallExpression || element instanceof PsiIdentifier)) {
47+
} else if ((element instanceof PsiMethodCallExpression || element instanceof PsiNewExpression || element instanceof PsiIdentifier)) {
4448
final Publisher publisher = publisherManager.resolveEventPublisher(element);
4549
final Handler handler = handlerManager.resolveEventHandler(element.getContext());
4650
if (publisher != null) {
@@ -55,7 +59,7 @@ public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolde
5559
if (handler != null) {
5660
Collection<Publisher> publishers = publisherManager.getRepository()
5761
.getPublishersFor(handler.getHandledType());
58-
createGutterIconForEventPublishers(
62+
createGutterIconForPublishers(
5963
handler.getElementForAnnotation(),
6064
holder,
6165
createNotNullLazyValueForPublishers(publishers));
@@ -112,7 +116,7 @@ private void tryAnnotateEventClass(AnnotationHolder holder, PsiClass classElemen
112116
PublisherProviderManager publisherManager, HandlerProviderManager handlerManager) {
113117
Set<Publisher> publishers = publisherManager.getRepository().getPublishersFor(PsiTypesUtil.getClassType(classElement));
114118
if (!publishers.isEmpty()) {
115-
createGutterIconForEventPublishers(
119+
createGutterIconForPublishers(
116120
classElement.getNameIdentifier(),
117121
holder,
118122
createNotNullLazyValueForPublishers(publishers));
@@ -134,8 +138,8 @@ private void addCreateEventHandlerQuickFixes(Publisher publisher, Annotation gut
134138
gutterIconForPublisher.registerFix(new CreateEventHandlerQuickfix(publisher.getPublishedType(), AnnotationTypes.SAGA_EVENT_HANDLER));
135139
}
136140

137-
private static Annotation createGutterIconForEventPublishers(PsiElement psiElement, AnnotationHolder holder,
138-
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver) {
141+
private static Annotation createGutterIconForPublishers(PsiElement psiElement, AnnotationHolder holder,
142+
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver) {
139143
return NavigationGutterIconBuilder.create(AxonIconIn)
140144
.setEmptyPopupText("No publishers found for this event")
141145
.setTargets(targetResolver)

src/main/java/org/axonframework/intellij/ide/plugin/publisher/DefaultEventPublisherProvider.java

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,45 @@
11
package org.axonframework.intellij.ide.plugin.publisher;
22

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+
313
import com.intellij.openapi.fileTypes.StdFileTypes;
414
import com.intellij.openapi.project.Project;
515
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;
727
import com.intellij.psi.search.GlobalSearchScope;
828
import com.intellij.psi.search.searches.MethodReferencesSearch;
929
import com.intellij.psi.search.searches.ReferencesSearch;
1030
import com.intellij.psi.util.PsiTreeUtil;
1131
import com.intellij.util.Processor;
1232
import com.intellij.util.Query;
1333

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-
2134
class DefaultEventPublisherProvider implements PublisherProvider {
2235

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>>();
2437

2538
@Override
2639
public void scanPublishers(final Project project, GlobalSearchScope scope, final Registrar registrar) {
2740
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);
3043
psiMethods.addAll(findMethods(project, GlobalSearchScope.allScope(project),
3144
"org.axonframework.eventsourcing.AbstractEventSourcedAggregateRoot", "apply"));
3245
psiMethods.addAll(findMethods(project, GlobalSearchScope.allScope(project),
@@ -51,7 +64,7 @@ public boolean process(PsiReference psiReference) {
5164
PsiMethod method = (PsiMethod) PsiTreeUtil.findFirstParent(psiReference.getElement(),
5265
new IsMethodWithParameterCondition());
5366
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());
5568
PsiParameter firstCommandHandlerArgument = method.getParameterList().getParameters()[0];
5669
if (methodIsAnnotatedAsCommandHandler(methodAnnotation)) {
5770
PsiTypeElement firstCommandHandlerArgumentType = firstCommandHandlerArgument.getTypeElement();
@@ -73,8 +86,10 @@ private boolean methodIsAnnotatedAsCommandHandler(PsiAnnotation methodCommandHan
7386

7487
private void findAndRegisterAllConstructors(PsiTypeElement firstCommandHandlerArgumentType) {
7588
final PsiType type = firstCommandHandlerArgumentType.getType();
89+
GlobalSearchScope scopeNarrowedToJavaSourceFiles =
90+
GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), StdFileTypes.JAVA);
7691
PsiClass parameterClass = JavaPsiFacade.getInstance(project)
77-
.findClass(type.getCanonicalText(), GlobalSearchScope.allScope(project));
92+
.findClass(type.getCanonicalText(), scopeNarrowedToJavaSourceFiles);
7893
if (parameterClass != null) {
7994
PsiMethod[] constructors = parameterClass.getConstructors();
8095
if (parameterClassHasConstructor(constructors)) {
@@ -83,40 +98,44 @@ private void findAndRegisterAllConstructors(PsiTypeElement firstCommandHandlerAr
8398
}
8499
}
85100

86-
private boolean parameterClassHasConstructor(PsiMethod[] constructors) {
87-
return constructors.length > 0;
88-
}
89-
90101
private void registerAllConstructorInvocations(final PsiType type, PsiMethod[] constructors) {
91102
for (PsiMethod constructor : constructors) {
92103
Query<PsiReference> constructorCalls = MethodReferencesSearch.search(constructor);
93104
constructorCalls.forEachAsync(new Processor<PsiReference>() {
94105
@Override
95106
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+
97112
return true;
98113
}
99114
});
100115
}
101116
}
102-
103-
private boolean methodHasParameter(PsiMethod method) {
104-
return method != null && method.getParameterList().getParametersCount() > 0;
105-
}
106117
});
107118
}
108119
}
109120

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+
110129
private PsiClass findCommandHandlersAnnotation(Project project) {
111130
return JavaPsiFacade.getInstance(project)
112131
.findClass("org.axonframework.commandhandling.annotation.CommandHandler",
113132
GlobalSearchScope.allScope(project));
114133
}
115134

116135
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)) {
118137
Query<PsiReference> invocations =
119-
MethodReferencesSearch.search(method, scope, false);
138+
MethodReferencesSearch.search((PsiMethod) method, scope, false);
120139
invocations.forEachAsync(new Processor<PsiReference>() {
121140
@Override
122141
public boolean process(PsiReference psiReference) {
@@ -166,14 +185,24 @@ private Set<PsiMethod> findMethods(Project project, GlobalSearchScope allScope,
166185
public Publisher resolve(PsiElement element) {
167186
if (element instanceof PsiMethodCallExpression) {
168187
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
172191
&& expression.getMethodExpression().isReferenceTo(method)) {
192+
PsiType[] expressionTypes = expression.getArgumentList().getExpressionTypes();
173193
return new DefaultEventPublisher(expressionTypes[0], element);
174194
}
175195
}
176196
}
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+
}
177206
return null;
178207
}
179208
}

0 commit comments

Comments
 (0)