1 package com.atlassian.johnson;
2
3 import com.atlassian.johnson.event.Event;
4
5 import javax.annotation.Nonnull;
6 import javax.annotation.ParametersAreNonnullByDefault;
7 import java.util.Collection;
8 import java.util.Optional;
9 import java.util.function.Predicate;
10
11 /**
12 * Interface defining a container for Johnson {@link Event}s
13 * <p>
14 * Johnson maintains <i>exactly one</i> event container, which is accessed statically. As a result, all implementations
15 * of this interface are required to be thread-safe. However, because Johnson may be used to filter all requests to the
16 * application, implementations should be careful in how they achieve that thread-safety. Using heavy synchronisation
17 * techniques may impose significant performance penalties.
18 *
19 * @since 2.0
20 */
21 @ParametersAreNonnullByDefault
22 public interface JohnsonEventContainer {
23
24 /**
25 * Adds the provided event to the collection.
26 *
27 * @param event the event to add
28 */
29 void addEvent(Event event);
30
31 /**
32 * Retrieves an <i>immutable</i> view of the contained {@link Event}s.
33 *
34 * @return the current events
35 */
36 @Nonnull
37 Collection<Event> getEvents();
38
39 /**
40 * Retrieves a flag indicating whether there are {@link Event}s in the container.
41 * <p>
42 * This can be thought of as a shortcut for {@code !getEvents().isEmpty()}.
43 *
44 * @return {@code true} if there are events; otherwise, {@code false}
45 */
46 boolean hasEvents();
47
48 /**
49 * Removes the specified {@link Event} from the container, if it can be found.
50 * <p>
51 * Warning: Due to how {@link Event#equals(Object)} and {@link Event#hashCode()} are implemented, an <i>exact</i>
52 * match on every field is required in order to match an event. As a result, it may be necessary to iterate over
53 * the {@link #getEvents() events} in the collection and remove the event using the exact instance already in the
54 * collection.
55 *
56 * @param event the event to remove
57 */
58 void removeEvent(Event event);
59
60 /**
61 * Returns any events that satisfy the given predicate.
62 *
63 * @param predicate the predicate to evaluate
64 * @return any matching events in their original iteration order
65 * @since 3.2
66 */
67 Collection<Event> getEvents(Predicate<? super Event> predicate);
68
69 /**
70 * Indicates whether this container has any events that satisfy the given predicate.
71 *
72 * This is equivalent to calling {@link #firstEvent(Predicate)} followed by
73 * {@link Optional#isPresent()}.
74 *
75 * @param predicate the predicate to evaluate
76 * @return <code>false</code>if no events match
77 * @since 3.2
78 */
79 boolean hasEvent(Predicate<? super Event> predicate);
80
81 /**
82 * Returns the first event (if any) that satisfies the given predicate.
83 *
84 * @param predicate the predicate to evaluate
85 * @return the first such event in container iteration order
86 * @see JohnsonEventContainer#getEvents()
87 * @since 3.2
88 */
89 Optional<Event> firstEvent(Predicate<? super Event> predicate);
90 }