Skip to content

Commit d84d7a4

Browse files
committed
Merge pull request #6 from pbadenski/navigation-from-events-and-commands
Add navigation from event classes and command classes to handlers
2 parents 5104ded + e2d858c commit d84d7a4

File tree

6 files changed

+141
-57
lines changed

6 files changed

+141
-57
lines changed

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

Lines changed: 100 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import com.intellij.lang.annotation.Annotator;
77
import com.intellij.openapi.util.IconLoader;
88
import com.intellij.openapi.util.NotNullLazyValue;
9+
import com.intellij.psi.PsiClass;
910
import com.intellij.psi.PsiElement;
1011
import com.intellij.psi.PsiIdentifier;
1112
import com.intellij.psi.PsiMethodCallExpression;
13+
import com.intellij.psi.util.PsiTypesUtil;
1214
import org.axonframework.intellij.ide.plugin.handler.AnnotationTypes;
1315
import org.axonframework.intellij.ide.plugin.handler.EventHandler;
1416
import org.axonframework.intellij.ide.plugin.handler.HandlerProviderManager;
@@ -33,53 +35,96 @@ public class AxonGutterAnnotator implements Annotator {
3335

3436
@Override
3537
public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
36-
if (!(element instanceof PsiMethodCallExpression || element instanceof PsiIdentifier)) {
37-
return;
38-
}
39-
4038
final PublisherProviderManager publisherManager = PublisherProviderManager.getInstance(element.getProject());
4139
final HandlerProviderManager handlerManager = HandlerProviderManager.getInstance(element.getProject());
42-
final EventPublisher publisher = publisherManager.resolveEventPublisher(element);
43-
final EventHandler handler = handlerManager.resolveEventHandler(element.getContext());
44-
if (publisher != null) {
45-
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver = new NotNullLazyValue<Collection<? extends PsiElement>>() {
46-
@NotNull
47-
@Override
48-
protected Collection<? extends PsiElement> compute() {
49-
Set<EventHandler> handlers = handlerManager.getRepository().findHandlers(publisher.getPublishedType());
50-
Set<PsiEventHandlerWrapper> destinations = new TreeSet<PsiEventHandlerWrapper>();
51-
for (EventHandler eventHandler : handlers) {
52-
PsiElement elementForAnnotation = eventHandler.getElementForAnnotation();
53-
if (elementForAnnotation.isValid()) {
54-
destinations.add(new PsiEventHandlerWrapper(elementForAnnotation, eventHandler));
55-
}
56-
}
57-
return destinations;
40+
if (element instanceof PsiClass) {
41+
tryAnnotateEventClass(holder, (PsiClass) element, publisherManager, handlerManager);
42+
tryAnnotateCommandClass(holder, (PsiClass) element, handlerManager);
43+
} else if ((element instanceof PsiMethodCallExpression || element instanceof PsiIdentifier)) {
44+
final EventPublisher publisher = publisherManager.resolveEventPublisher(element);
45+
final EventHandler handler = handlerManager.resolveEventHandler(element.getContext());
46+
if (publisher != null) {
47+
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver =
48+
createNotNullLazyValueForHandlers(handlerManager.getRepository().findHandlers(publisher.getPublishedType()));
49+
Annotation gutterIconForPublisher = createGutterIconForEventHandlers(element, holder, targetResolver, handlerManager);
50+
if (targetResolver.getValue().isEmpty()) {
51+
addCreateEventHandlerQuickFixes(publisher, gutterIconForPublisher);
5852
}
59-
};
60-
Annotation gutterIconForPublisher = createGutterIconForPublisher(element, holder, targetResolver, handlerManager);
61-
if (targetResolver.getValue().isEmpty()) {
62-
addCreateEventHandlerQuickFixes(publisher, gutterIconForPublisher);
53+
}
54+
55+
if (handler != null) {
56+
Collection<EventPublisher> publishers = publisherManager.getRepository()
57+
.getPublishersFor(handler.getHandledType());
58+
createGutterIconForEventPublishers(
59+
handler.getElementForAnnotation(),
60+
holder,
61+
createNotNullLazyValueForPublishers(publishers));
6362
}
6463
}
64+
}
6565

66-
if (handler != null) {
67-
createGutterIconForHandler(handler.getElementForAnnotation(), holder, new NotNullLazyValue<Collection<? extends PsiElement>>() {
68-
@NotNull
69-
@Override
70-
protected Collection<? extends PsiElement> compute() {
71-
Collection<EventPublisher> publishers = publisherManager.getRepository()
72-
.getPublishersFor(handler.getHandledType());
73-
Collection<PsiElement> publishLocations = new ArrayList<PsiElement>();
74-
for (EventPublisher eventPublisher : publishers) {
75-
PsiElement psiElement = eventPublisher.getPsiElement();
76-
if (psiElement.isValid()) {
77-
publishLocations.add(psiElement);
78-
}
66+
private NotNullLazyValue<Collection<? extends PsiElement>> createNotNullLazyValueForPublishers(final Collection<EventPublisher> publishers) {
67+
return new NotNullLazyValue<Collection<? extends PsiElement>>() {
68+
@NotNull
69+
@Override
70+
protected Collection<? extends PsiElement> compute() {
71+
Collection<PsiElement> publishLocations = new ArrayList<PsiElement>();
72+
for (EventPublisher eventPublisher : publishers) {
73+
PsiElement psiElement = eventPublisher.getPsiElement();
74+
if (psiElement.isValid()) {
75+
publishLocations.add(psiElement);
7976
}
80-
return publishLocations;
8177
}
82-
});
78+
return publishLocations;
79+
}
80+
};
81+
}
82+
83+
private NotNullLazyValue<Collection<? extends PsiElement>> createNotNullLazyValueForHandlers(final Set<EventHandler> handlers) {
84+
return new NotNullLazyValue<Collection<? extends PsiElement>>() {
85+
@NotNull
86+
@Override
87+
protected Collection<? extends PsiElement> compute() {
88+
Set<PsiEventHandlerWrapper> destinations = new TreeSet<PsiEventHandlerWrapper>();
89+
for (EventHandler eventHandler : handlers) {
90+
PsiElement elementForAnnotation = eventHandler.getElementForAnnotation();
91+
if (elementForAnnotation.isValid()) {
92+
destinations.add(new PsiEventHandlerWrapper(elementForAnnotation, eventHandler));
93+
}
94+
}
95+
return destinations;
96+
}
97+
};
98+
}
99+
100+
private void tryAnnotateCommandClass(AnnotationHolder holder, PsiClass classElement, HandlerProviderManager handlerManager) {
101+
Set<EventHandler> handlers =
102+
handlerManager.getRepository().findCommandHandlers(PsiTypesUtil.getClassType(classElement));
103+
if (!handlers.isEmpty()) {
104+
createGutterIconForCommandHandlers(
105+
classElement.getNameIdentifier(),
106+
holder,
107+
createNotNullLazyValueForHandlers(handlers));
108+
}
109+
}
110+
111+
private void tryAnnotateEventClass(AnnotationHolder holder, PsiClass classElement,
112+
PublisherProviderManager publisherManager, HandlerProviderManager handlerManager) {
113+
Set<EventPublisher> publishers = publisherManager.getRepository().getPublishersFor(PsiTypesUtil.getClassType(classElement));
114+
if (!publishers.isEmpty()) {
115+
createGutterIconForEventPublishers(
116+
classElement.getNameIdentifier(),
117+
holder,
118+
createNotNullLazyValueForPublishers(publishers));
119+
}
120+
Set<EventHandler> handlers =
121+
handlerManager.getRepository().findEventHandlers(PsiTypesUtil.getClassType(classElement));
122+
if (!handlers.isEmpty()) {
123+
createGutterIconForEventHandlers(
124+
classElement.getNameIdentifier(),
125+
holder,
126+
createNotNullLazyValueForHandlers(handlers),
127+
handlerManager);
83128
}
84129
}
85130

@@ -89,8 +134,8 @@ private void addCreateEventHandlerQuickFixes(EventPublisher publisher, Annotatio
89134
gutterIconForPublisher.registerFix(new CreateEventHandlerQuickfix(publisher.getPublishedType(), AnnotationTypes.SAGA_EVENT_HANDLER));
90135
}
91136

92-
private static Annotation createGutterIconForHandler(PsiElement psiElement, AnnotationHolder holder,
93-
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver) {
137+
private static Annotation createGutterIconForEventPublishers(PsiElement psiElement, AnnotationHolder holder,
138+
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver) {
94139
return NavigationGutterIconBuilder.create(AxonIconIn)
95140
.setEmptyPopupText("No publishers found for this event")
96141
.setTargets(targetResolver)
@@ -100,8 +145,20 @@ private static Annotation createGutterIconForHandler(PsiElement psiElement, Anno
100145
.install(holder, psiElement);
101146
}
102147

103-
private static Annotation createGutterIconForPublisher(PsiElement psiElement, AnnotationHolder holder,
104-
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver, HandlerProviderManager handlerManager) {
148+
private static Annotation createGutterIconForCommandHandlers(PsiElement psiElement, AnnotationHolder holder,
149+
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver) {
150+
return NavigationGutterIconBuilder.create(AxonIconIn)
151+
.setEmptyPopupText("No handlers found for this command")
152+
.setTargets(targetResolver)
153+
.setPopupTitle("Command handlers")
154+
.setCellRenderer(new ContainingMethodCellRenderer())
155+
.setTooltipText("Navigate to the handlers")
156+
.install(holder, psiElement);
157+
}
158+
159+
private static Annotation createGutterIconForEventHandlers(PsiElement psiElement, AnnotationHolder holder,
160+
NotNullLazyValue<Collection<? extends PsiElement>> targetResolver,
161+
HandlerProviderManager handlerManager) {
105162
return NavigationGutterIconBuilder.create(AxonIconOut)
106163
.setEmptyPopupText("No handlers found for this event")
107164
.setTargets(targetResolver)

src/main/java/org/axonframework/intellij/ide/plugin/handler/AnnotationTypes.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,4 @@ public String getRequiredProperty() {
3232
return requiredProperty;
3333
}
3434

35-
public boolean isCommand() {
36-
return this.annotation.equals("@CommandHandler");
37-
}
3835
}

src/main/java/org/axonframework/intellij/ide/plugin/handler/DefaultEventHandlerProvider.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.intellij.util.Query;
1010

1111
class DefaultEventHandlerProvider implements EventHandlerProvider {
12-
1312
@Override
1413
public void scanHandlers(Project project, GlobalSearchScope scope, final Registrar registrar) {
1514
for (final AnnotationTypes annotationType : AnnotationTypes.values()) {
@@ -27,12 +26,7 @@ public boolean process(PsiReference psiReference) {
2726
// this doesn't say the method is annotated
2827
final PsiAnnotation annotation = locateAnnotation(method);
2928
if (annotation != null) {
30-
EventHandler handler;
31-
if (annotationType.isCommand()) {
32-
handler = CommandEventHandler.createEventHandler(method);
33-
} else {
34-
handler = DefaultEventHandler.createEventHandler(method, annotation);
35-
}
29+
EventHandler handler = createHandlerBasedOnAnnotation(method, annotation);
3630
if (handler != null) {
3731
registrar.registerHandler(handler);
3832
}
@@ -48,14 +42,23 @@ public boolean process(PsiReference psiReference) {
4842
@Override
4943
public EventHandler resolve(PsiElement element) {
5044
if (element instanceof PsiMethod) {
51-
final PsiAnnotation annotation = locateAnnotation((PsiMethod) element);
45+
PsiMethod methodElement = (PsiMethod) element;
46+
final PsiAnnotation annotation = locateAnnotation(methodElement);
5247
if (annotation != null) {
53-
return DefaultEventHandler.createEventHandler((PsiMethod) element, annotation);
48+
return createHandlerBasedOnAnnotation(methodElement, annotation);
5449
}
5550
}
5651
return null;
5752
}
5853

54+
private EventHandler createHandlerBasedOnAnnotation(PsiMethod method, PsiAnnotation annotation) {
55+
if (annotation.getText().equals(AnnotationTypes.COMMAND_EVENT_HANDLER.getAnnotation())) {
56+
return CommandEventHandler.createEventHandler(method);
57+
} else {
58+
return DefaultEventHandler.createEventHandler(method, annotation);
59+
}
60+
}
61+
5962
private PsiAnnotation locateAnnotation(PsiMethod element) {
6063
for (AnnotationTypes annotationType : AnnotationTypes.values()) {
6164
PsiAnnotation annotation = element.getModifierList().findAnnotation(annotationType.getFullyQualifiedName());

src/main/java/org/axonframework/intellij/ide/plugin/handler/DefaultEventHandlerRepository.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,26 @@ public Set<EventHandler> findHandlers(PsiType eventType) {
3333
}
3434
return found;
3535
}
36+
37+
@Override
38+
public Set<EventHandler> findEventHandlers(PsiType eventType) {
39+
Set<EventHandler> found = new HashSet<EventHandler>();
40+
for (EventHandler eventHandler : findHandlers(eventType)) {
41+
if (!(eventHandler instanceof CommandEventHandler)) {
42+
found.add(eventHandler);
43+
}
44+
}
45+
return found;
46+
}
47+
48+
@Override
49+
public Set<EventHandler> findCommandHandlers(PsiType eventType) {
50+
Set<EventHandler> found = new HashSet<EventHandler>();
51+
for (EventHandler eventHandler : findHandlers(eventType)) {
52+
if (eventHandler instanceof CommandEventHandler) {
53+
found.add(eventHandler);
54+
}
55+
}
56+
return found;
57+
}
3658
}

src/main/java/org/axonframework/intellij/ide/plugin/handler/EventHandlerRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ public interface EventHandlerRepository {
99
void registerHandler(EventHandler eventHandler);
1010

1111
Set<EventHandler> findHandlers(PsiType eventType);
12+
13+
Set<EventHandler> findEventHandlers(PsiType eventType);
14+
15+
Set<EventHandler> findCommandHandlers(PsiType eventType);
1216
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ public boolean canPublishType(PsiType eventType) {
2020
&& publishedType != null
2121
&& eventType.isValid()
2222
&& (eventType.isAssignableFrom(publishedType)
23-
|| eventType instanceof PsiImmediateClassType
24-
&& ((PsiImmediateClassType) eventType).getParameters()[0].isAssignableFrom(publishedType));
23+
|| (eventType instanceof PsiImmediateClassType
24+
&& ((PsiImmediateClassType) eventType).getParameterCount() > 0
25+
&& ((PsiImmediateClassType) eventType).getParameters()[0].isAssignableFrom(publishedType)));
2526

2627
}
2728

0 commit comments

Comments
 (0)