Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use jspecify nullable annotations #241

Merged
merged 2 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ projectConfiguration {
}

dependencies {

// annotations
implementation("org.jspecify:jspecify:1.0.0")
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.github.philippheuer.events4j.api.domain.IEventSubscription;
import com.github.philippheuer.events4j.api.service.IEventHandler;
import com.github.philippheuer.events4j.api.service.IServiceMediator;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.List;
import java.util.function.Consumer;
Expand All @@ -15,14 +17,14 @@ public interface IEventManager extends AutoCloseable {
*
* @param event Event
*/
void publish(Object event);
void publish(@NonNull Object event);

/**
* Register EventHandler
*
* @param eventHandler IEventHandler
*/
void registerEventHandler(IEventHandler eventHandler);
void registerEventHandler(@NonNull IEventHandler eventHandler);

/**
* Registers a new consumer based default event handler if supported
Expand All @@ -32,13 +34,15 @@ public interface IEventManager extends AutoCloseable {
* @param <E> the event type
* @return a new Disposable of the given eventType
*/
<E> IDisposable onEvent(Class<E> eventClass, Consumer<E> consumer);
@NonNull
<E> IDisposable onEvent(@NonNull Class<E> eventClass, @NonNull Consumer<E> consumer);

/**
* Get the ServiceMediator
*
* @return ServiceMediator
*/
@NonNull
IServiceMediator getServiceMediator();

/**
Expand All @@ -47,29 +51,33 @@ public interface IEventManager extends AutoCloseable {
* @param eventHandlerClass the event handler class
* @return boolean
*/
boolean hasEventHandler(Class<? extends IEventHandler> eventHandlerClass);
boolean hasEventHandler(@NonNull Class<? extends IEventHandler> eventHandlerClass);

/**
* Retrieves a EventHandler of the provided type
*
* @param eventHandlerClass the event handler class
* @param <E> the eventHandler type
* @throws RuntimeException if no event handler of the provided type is registered
* @return a reference to the requested event handler
*/
<E extends IEventHandler> E getEventHandler(Class<E> eventHandlerClass);
@NonNull
<E extends IEventHandler> E getEventHandler(@NonNull Class<E> eventHandlerClass);

/**
* Gets all registered event handlers
*
* @return a list of all registered event handlers
*/
@NonNull
List<IEventHandler> getEventHandlers();

/**
* Gets a list of all active subscriptions
*
* @return a list that holds IEventSubscription`s
*/
@NonNull
List<IEventSubscription> getActiveSubscriptions();

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.Getter;
import lombok.ToString;
import org.jspecify.annotations.NonNull;

import java.util.Map;
import java.util.function.Consumer;
Expand All @@ -24,7 +25,7 @@ public class DisposableWrapper implements IEventSubscription {
private final Map<String, IEventSubscription> activeSubscriptions;

@SuppressWarnings("rawtypes")
public DisposableWrapper(IDisposable disposable, String id, Class eventType, Consumer consumer, Map<String, IEventSubscription> activeSubscriptions) {
public DisposableWrapper(@NonNull IDisposable disposable, @NonNull String id, @NonNull Class eventType, @NonNull Consumer consumer, @NonNull Map<String, IEventSubscription> activeSubscriptions) {
this.disposable = disposable;
this.id = id;
this.eventType = eventType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.github.philippheuer.events4j.api.domain;

import org.jspecify.annotations.NonNull;

import java.util.function.Consumer;

public interface IEventSubscription extends IDisposable {

@NonNull
String getId();

@NonNull
@SuppressWarnings("rawtypes")
Class getEventType();

@NonNull
@SuppressWarnings("rawtypes")
Consumer getConsumer();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.philippheuer.events4j.api.service;

import com.github.philippheuer.events4j.api.domain.IDisposable;
import lombok.NonNull;

import java.util.function.Consumer;

Expand All @@ -11,7 +12,7 @@ public interface IEventHandler extends AutoCloseable {
*
* @param event Event
*/
void publish(Object event);
void publish(@NonNull Object event);

/**
* Registers a new consumer based default event handler if supported
Expand All @@ -21,6 +22,6 @@ public interface IEventHandler extends AutoCloseable {
* @param <E> the event type
* @return a new Disposable of the given eventType
*/
<E> IDisposable onEvent(Class<E> eventClass, Consumer<E> consumer);
<E> IDisposable onEvent(@NonNull Class<E> eventClass, @NonNull Consumer<E> consumer);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.philippheuer.events4j.api.service;

import org.jspecify.annotations.NonNull;

public interface IServiceMediator {

/**
Expand All @@ -8,16 +10,18 @@ public interface IServiceMediator {
* @param serviceName The ServiceName
* @param serviceInstance The ServiceInstance
*/
void addService(String serviceName, Object serviceInstance);
void addService(@NonNull String serviceName, @NonNull Object serviceInstance);

/**
* Gets a service from the ServiceMediator
*
* @param serviceClass The ServiceClass you expect
* @param serviceName The ServiceName
* @param <T> The type of the Service
* @throws RuntimeException if no service of the provided type and name is registered
* @return The ServiceInstance
*/
<T> T getService(Class<T> serviceClass, String serviceName);
@NonNull
<T> T getService(@NonNull Class<T> serviceClass, @NonNull String serviceName);

}
5 changes: 4 additions & 1 deletion core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ projectConfiguration {
}

dependencies {
// Project
// project
api(project(":api"))
testImplementation(project(":handler-simple"))
testImplementation(project(":handler-reactor"))

// annotations
implementation("org.jspecify:jspecify:1.0.0")
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import com.github.philippheuer.events4j.core.services.ServiceMediator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
Expand All @@ -23,10 +25,6 @@

/**
* The EventManager
*
* @author Philipp Heuer [https://github.com/PhilippHeuer]
* @version %I%, %G%
* @since 1.0
*/
@Getter
@Slf4j
Expand Down Expand Up @@ -79,7 +77,7 @@ public EventManager() {
*
* @param eventHandler IEventHandler
*/
public void registerEventHandler(IEventHandler eventHandler) {
public void registerEventHandler(@NonNull IEventHandler eventHandler) {
if (!eventHandlers.contains(eventHandler)) {
eventHandlers.add(eventHandler);
eventHandlerCache.put(eventHandler.getClass().getCanonicalName(), eventHandler.getClass());
Expand All @@ -89,6 +87,7 @@ public void registerEventHandler(IEventHandler eventHandler) {
/**
* @return returns the list of all active subscriptions
*/
@NonNull
public List<IEventSubscription> getActiveSubscriptions() {
return Collections.unmodifiableList(new ArrayList<>(activeSubscriptions.values()));
}
Expand Down Expand Up @@ -126,7 +125,7 @@ public void autoDiscovery() {
*
* @param event A event of any kinds, should implement IEvent if possible
*/
public void publish(Object event) {
public void publish(@NonNull Object event) {
// check for stop
if (isStopped) {
log.warn("Tried to dispatch a event to a closed eventManager!");
Expand Down Expand Up @@ -163,7 +162,7 @@ public void publish(Object event) {
* @param eventHandlerClass the event handler class
* @return boolean
*/
public boolean hasEventHandler(Class<? extends IEventHandler> eventHandlerClass) {
public boolean hasEventHandler(@NonNull Class<? extends IEventHandler> eventHandlerClass) {
return getEventHandlers().stream().anyMatch(h -> h.getClass().getName().equalsIgnoreCase(eventHandlerClass.getName()));
}

Expand All @@ -174,7 +173,8 @@ public boolean hasEventHandler(Class<? extends IEventHandler> eventHandlerClass)
* @param <E> the eventHandler type
* @return a reference to the requested event handler
*/
public <E extends IEventHandler> E getEventHandler(Class<E> eventHandlerClass) {
@NonNull
public <E extends IEventHandler> E getEventHandler(@NonNull Class<E> eventHandlerClass) {
Optional<E> eventHandler = getEventHandlers().stream().filter(h -> h.getClass().getName().equalsIgnoreCase(eventHandlerClass.getName())).map(h -> (E) h).findAny();
return eventHandler.orElseThrow(() -> new RuntimeException("No eventHandler of type " + eventHandlerClass.getName() + " is registered!"));
}
Expand All @@ -187,8 +187,14 @@ public <E extends IEventHandler> E getEventHandler(Class<E> eventHandlerClass) {
* @param <E> the event type
* @return a new Disposable of the given eventType
*/
public <E> IEventSubscription onEvent(Class<E> eventClass, Consumer<E> consumer) {
return onEvent(consumer.getClass().getCanonicalName() + "/" + consumerSequence.getAndAdd(1), eventClass, consumer);
@NonNull
public <E> IEventSubscription onEvent(@NonNull Class<E> eventClass, @NonNull Consumer<E> consumer) {
IEventSubscription sub;
do {
sub = onEvent(consumer.getClass().getCanonicalName() + "/" + consumerSequence.getAndAdd(1), eventClass, consumer);
} while (sub == null);

return sub;
}

/**
Expand All @@ -202,7 +208,8 @@ public <E> IEventSubscription onEvent(Class<E> eventClass, Consumer<E> consumer)
* @param <E> the event type
* @return a new Disposable of the given eventType
*/
public synchronized <E> IEventSubscription onEvent(String id, Class<E> eventClass, Consumer<E> consumer) {
@Nullable
public synchronized <E> IEventSubscription onEvent(@NonNull String id, @NonNull Class<E> eventClass, @NonNull Consumer<E> consumer) {
// return null if a disposable with the given id is already present when idUnique is set
if (activeSubscriptions.containsKey(id)) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@

/**
* Used to represent an event.
*
* @author Philipp Heuer [https://github.com/PhilippHeuer]
* @version %I%, %G%
* @since 1.0
*/
@Data
public abstract class Event implements IEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.philippheuer.events4j.api.IEventManager;
import com.github.philippheuer.events4j.api.service.IServiceMediator;
import lombok.Getter;
import org.jspecify.annotations.NonNull;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -11,10 +12,6 @@
* The ServiceMediator
* <p>
* The ServiceMediator provides access to 3rd party services for your custom events
*
* @author Philipp Heuer [https://github.com/PhilippHeuer]
* @version %I%, %G%
* @since 1.0
*/
public final class ServiceMediator implements IServiceMediator {

Expand Down Expand Up @@ -44,7 +41,7 @@ public ServiceMediator(final IEventManager eventManager) {
* @param serviceName The ServiceName
* @param serviceInstance The ServiceInstance
*/
public void addService(String serviceName, Object serviceInstance) {
public void addService(@NonNull String serviceName, @NonNull Object serviceInstance) {
serviceReferences.put(serviceName, serviceInstance);
}

Expand All @@ -56,7 +53,8 @@ public void addService(String serviceName, Object serviceInstance) {
* @param <T> The type of the Service
* @return The ServiceInstance
*/
public <T> T getService(Class<T> serviceClass, String serviceName) {
@NonNull
public <T> T getService(@NonNull Class<T> serviceClass, @NonNull String serviceName) {
Object serviceInstance = serviceReferences.get(serviceName);

if (serviceClass.isInstance(serviceInstance)) {
Expand Down
7 changes: 5 additions & 2 deletions handler-reactor/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ projectConfiguration {
}

dependencies {
// Project
// project
api(project(":api"))
testImplementation(project(":core"))

// Reactor - see https://repo1.maven.org/maven2/io/projectreactor/reactor-bom/Dysprosium-SR12/reactor-bom-Dysprosium-SR12.pom
// reactor - see https://repo1.maven.org/maven2/io/projectreactor/reactor-bom/Dysprosium-SR12/reactor-bom-Dysprosium-SR12.pom
api("io.projectreactor:reactor-core:3.7.2")
api("io.projectreactor.addons:reactor-extra:3.5.2")
testImplementation("io.projectreactor:reactor-test:3.7.2")

// annotations
implementation("org.jspecify:jspecify:1.0.0")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.github.philippheuer.events4j.reactor.util.Events4JSubscriber;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jspecify.annotations.NonNull;
import org.reactivestreams.Subscriber;
import reactor.core.publisher.EmitterProcessor;
import reactor.core.publisher.Flux;
Expand Down Expand Up @@ -53,7 +54,7 @@ public ReactorEventHandler() {
*
* @param scheduler The scheduler provides some guarantees required by Reactive Streams flows like FIFO execution
* @param processor Used to bridge gateway events to the subscribers
* @param overflowStrategy Safely gates a multi-threaded producer.
* @param overflowStrategy Safely gates a multithreaded producer.
* @deprecated {@link FluxProcessor} is deprecated.
*/
@Deprecated
Expand All @@ -64,7 +65,7 @@ public ReactorEventHandler(Scheduler scheduler, FluxProcessor<Object, Object> pr
}

@Override
public void publish(Object event) {
public void publish(@NonNull Object event) {
// publish event
eventSink.next(event);
}
Expand All @@ -77,8 +78,9 @@ public void publish(Object event) {
* @param <E> the event type
* @return a new {@link reactor.core.publisher.Flux} of the given eventType
*/
@NonNull
@Override
public <E> IDisposable onEvent(Class<E> eventClass, Consumer<E> consumer) {
public <E> IDisposable onEvent(@NonNull Class<E> eventClass, @NonNull Consumer<E> consumer) {
Flux<E> flux = processor
.publishOn(this.scheduler)
.ofType(eventClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

/**
* Reactor EventHandler Test
*
* @author Philipp Heuer [https://github.com/PhilippHeuer]
* @version %I%, %G%
* @since 1.0
*/
class ReactorEventHandlerTest {

Expand Down
Loading