1 package com.atlassian.plugin.event.events;
2
3 import com.atlassian.annotations.PublicApi;
4 import com.atlassian.plugin.ModuleDescriptor;
5 import com.atlassian.plugin.Plugin;
6 import com.google.common.collect.ImmutableList;
7
8 import java.util.List;
9 import java.util.function.Predicate;
10
11 /**
12 * Event send at the end of an action wrapping existing plugin events:
13 * <ul>
14 * <li>{@link PluginEnablingEvent}</li>
15 * <li>{@link PluginEnabledEvent}</li>
16 * <li>{@link PluginDisablingEvent}</li>
17 * <li>{@link PluginDisabledEvent}</li>
18 * <li>{@link PluginModuleDisablingEvent}</li>
19 * <li>{@link PluginModuleDisabledEvent}</li>
20 * <li>{@link PluginModuleEnablingEvent}</li>
21 * <li>{@link PluginModuleEnabledEvent}</li>
22 * <li>{@link PluginRefreshedEvent}</li>
23 * <li>{@link PluginFrameworkStartingEvent}</li>
24 * <li>{@link PluginFrameworkDelayedEvent}</li>
25 * <li>{@link PluginFrameworkResumingEvent}</li>
26 * <li>{@link PluginFrameworkStartedEvent}</li>
27 * <li>{@link PluginFrameworkShuttingDownEvent}</li>
28 * <li>{@link PluginFrameworkShutdownEvent}</li>
29 * <li>{@link PluginFrameworkWarmRestartingEvent}</li>
30 * <li>{@link PluginFrameworkWarmRestartedEvent}</li>
31 * <li>{@link PluginUninstallingEvent}</li>
32 * <li>{@link PluginUninstalledEvent}</li>
33 * <li>{@link PluginInstallingEvent}</li>
34 * <li>{@link PluginInstalledEvent}</li>
35 * <li>{@link PluginUpgradingEvent}</li>
36 * <li>{@link PluginUpgradedEvent}</li>
37 * <li>{@link PluginDependentsChangedEvent}</li>
38 * </ul>
39 *
40 * Contains information about plugin events which were part of this transaction.
41 *
42 * @see com.atlassian.plugin.event.events
43 * @since 5.1.3
44 */
45 @PublicApi
46 public class PluginTransactionEndEvent {
47
48 private final long threadId;
49 private final ImmutableList<Object> events;
50
51 public PluginTransactionEndEvent(final List<Object> events) {
52 this.events = ImmutableList.copyOf(events);
53 this.threadId = Thread.currentThread().getId();
54 }
55
56 public ImmutableList<Object> getEvents() {
57 return events;
58 }
59
60 public int numberOfEvents() {
61 return events.size();
62 }
63
64 /**
65 * Returns true if any event of type <code>eventTypeClass</code> matching <code>anyMatchEventPredicate</code> was
66 * part of this transaction.
67 */
68 public <T> boolean hasAnyEventOfTypeMatching(final Class<T> eventTypeClass, final Predicate<T> anyMatchEventPredicate) {
69 return events.stream()
70 .filter(eventTypeClass::isInstance)
71 .map(eventTypeClass::cast)
72 .anyMatch(anyMatchEventPredicate);
73 }
74
75 /**
76 * Returns true if any event of type {@link PluginModuleEvent} with {@link PluginModuleEvent#getModule()} matching
77 * <code>anyMatchModuleDescriptorPredicate</code> was part of this transaction, or if any event of type {@link PluginEvent}
78 * with {@link PluginEvent#getPlugin()} with any {@link Plugin#getModuleDescriptors()} matching
79 * <code>anyMatchModuleDescriptorPredicate</code> was part of this transaction.
80 */
81 public boolean hasAnyEventWithModuleDescriptorMatching(final Predicate<ModuleDescriptor<?>> anyMatchModuleDescriptorPredicate) {
82 return events.stream()
83 .filter(PluginModuleEvent.class::isInstance)
84 .map(PluginModuleEvent.class::cast)
85 .map(PluginModuleEvent::getModule)
86 .anyMatch(anyMatchModuleDescriptorPredicate) ||
87 events.stream()
88 .filter(PluginEvent.class::isInstance)
89 .map(PluginEvent.class::cast)
90 .map(PluginEvent::getPlugin)
91 .flatMap(plugin -> plugin.getModuleDescriptors().stream())
92 .anyMatch(anyMatchModuleDescriptorPredicate);
93 }
94
95 /**
96 * @return thread ID of the thread sending this event; can be used to match {@link PluginTransactionStartEvent} and {@link PluginTransactionEndEvent}
97 */
98 public long threadId() {
99 return threadId;
100 }
101 }