AbstractDomainEvent.java

1
package com.reallifedeveloper.common.domain.event;
2
3
import java.time.ZonedDateTime;
4
import java.util.Objects;
5
6
import org.checkerframework.checker.nullness.qual.Nullable;
7
8
import com.reallifedeveloper.common.domain.ErrorHandling;
9
import com.reallifedeveloper.common.domain.registry.CommonDomainRegistry;
10
11
/**
12
 * An abstract base class for domain events.
13
 *
14
 * @author RealLifeDeveloper
15
 */
16
public abstract class AbstractDomainEvent implements DomainEvent {
17
18
    private static final long serialVersionUID = 1L;
19
20
    /**
21
     * The timestamp when this event occurred.
22
     */
23
    private final ZonedDateTime eventOccurredOn;
24
25
    /**
26
     * The version of this event. In a long-lived system, it may be necessary to work with old versions of domaim events and keeping track
27
     * of the version makes this easier.
28
     */
29
    private final int eventVersion;
30
31
    /**
32
     * Creates a new {@code AbstractDomainEvent} that occurred now and has a version of 1.
33
     * <p>
34
     * The time of occurrence is taken from calling the {@link com.reallifedeveloper.common.domain.TimeService#now()} method on the
35
     * {@link CommonDomainRegistry#timeService()}.
36
     */
37
    public AbstractDomainEvent() {
38
        this(CommonDomainRegistry.timeService().now(), 1);
39
    }
40
41
    /**
42
     * Creates a new {@code AbstractDomainEvent} that occurred now and has the given version.
43
     * <p>
44
     * The time of occurrence is taken from calling the {@link com.reallifedeveloper.common.domain.TimeService#now()} method on the
45
     * {@link CommonDomainRegistry#timeService()}.
46
     *
47
     * @param eventVersion the version of the event
48
     */
49
    public AbstractDomainEvent(int eventVersion) {
50
        this(CommonDomainRegistry.timeService().now(), eventVersion);
51
    }
52
53
    /**
54
     * Creates a new {@code AbstractDomainEvent} that occurred at the given time and has a version of 1.
55
     *
56
     * @param eventOccurredOn the date and time the event occurred
57
     */
58
    public AbstractDomainEvent(ZonedDateTime eventOccurredOn) {
59
        this(eventOccurredOn, 1);
60
    }
61
62
    /**
63
     * Creates a new {@code AbstractDomainEvent} that occurred at the given time and has the given version.
64
     *
65
     * @param eventOccurredOn the time the event occurred
66
     * @param eventVersion    the version of the event
67
     */
68
    public AbstractDomainEvent(ZonedDateTime eventOccurredOn, int eventVersion) {
69 1 1. <init> : removed call to com/reallifedeveloper/common/domain/ErrorHandling::checkNull → KILLED
        ErrorHandling.checkNull("eventOccurredOn must not be null", eventOccurredOn);
70
        this.eventOccurredOn = eventOccurredOn;
71
        this.eventVersion = eventVersion;
72
    }
73
74
    @Override
75
    public ZonedDateTime eventOccurredOn() {
76 1 1. eventOccurredOn : replaced return value with null for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::eventOccurredOn → KILLED
        return eventOccurredOn;
77
    }
78
79
    @Override
80
    public int eventVersion() {
81 1 1. eventVersion : replaced int return with 0 for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::eventVersion → KILLED
        return eventVersion;
82
    }
83
84
    @Override
85
    public String toString() {
86 1 1. toString : replaced return value with "" for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::toString → KILLED
        return getClass().getSimpleName() + "{eventOccurredOn=" + eventOccurredOn() + ", eventVersion=" + eventVersion() + "}";
87
    }
88
89
    @Override
90
    public int hashCode() {
91 1 1. hashCode : replaced int return with 0 for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::hashCode → KILLED
        return Objects.hash(eventOccurredOn, eventVersion);
92
    }
93
94
    @Override
95
    public boolean equals(@Nullable Object obj) {
96 1 1. equals : negated conditional → KILLED
        if (this == obj) {
97 1 1. equals : replaced boolean return with false for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED
            return true;
98
        }
99 1 1. equals : negated conditional → KILLED
        if (obj instanceof AbstractDomainEvent other) {
100 3 1. equals : negated conditional → KILLED
2. equals : negated conditional → KILLED
3. equals : replaced boolean return with true for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED
            return Objects.equals(eventOccurredOn, other.eventOccurredOn) && eventVersion == other.eventVersion;
101
        } else {
102 1 1. equals : replaced boolean return with true for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED
            return false;
103
        }
104
    }
105
106
    /**
107
     * Make finalize method final to avoid "Finalizer attacks" and corresponding SpotBugs warning (CT_CONSTRUCTOR_THROW).
108
     *
109
     * @see <a href="https://wiki.sei.cmu.edu/confluence/display/java/OBJ11-J.+Be+wary+of+letting+constructors+throw+exceptions">
110
     *      Explanation of finalizer attack</a>
111
     */
112
    @Override
113
    @SuppressWarnings({ "checkstyle:NoFinalizer", "PMD.EmptyFinalizer", "PMD.EmptyMethodInAbstractClassShouldBeAbstract" })
114
    protected final void finalize() throws Throwable {
115
        // Do nothing
116
    }
117
}

Mutations

69

1.1
Location : <init>
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:constructorNullDateVersion()]
removed call to com/reallifedeveloper/common/domain/ErrorHandling::checkNull → KILLED

76

1.1
Location : eventOccurredOn
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:constructorDateTimeVersion()]
replaced return value with null for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::eventOccurredOn → KILLED

81

1.1
Location : eventVersion
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:constructorDateTimeVersion()]
replaced int return with 0 for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::eventVersion → KILLED

86

1.1
Location : toString
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testToString()]
replaced return value with "" for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::toString → KILLED

91

1.1
Location : hashCode
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
replaced int return with 0 for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::hashCode → KILLED

96

1.1
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
negated conditional → KILLED

97

1.1
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
replaced boolean return with false for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED

99

1.1
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
negated conditional → KILLED

100

1.1
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
negated conditional → KILLED

2.2
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
negated conditional → KILLED

3.3
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
replaced boolean return with true for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED

102

1.1
Location : equals
Killed by : com.reallifedeveloper.common.domain.event.DomainEventTest.[engine:junit-jupiter]/[class:com.reallifedeveloper.common.domain.event.DomainEventTest]/[method:testEqualsAndHashCode()]
replaced boolean return with true for com/reallifedeveloper/common/domain/event/AbstractDomainEvent::equals → KILLED

Active mutators

Tests examined


Report generated by PIT 1.20.0