io.gravitee.common.event.impl.EventManagerImpl Maven / Gradle / Ivy
The newest version!
/*
* Copyright © 2015 The Gravitee team (http://gravitee.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.gravitee.common.event.impl;
import io.gravitee.common.event.Event;
import io.gravitee.common.event.EventListener;
import io.gravitee.common.event.EventManager;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import lombok.extern.slf4j.Slf4j;
/**
* @author David BRASSELY (brasseld at gmail.com)
*/
@Slf4j
public class EventManagerImpl implements EventManager {
private final Map>, List>> listeners = new ConcurrentHashMap<>();
public , S> void publishEvent(final T type, final S content) {
this.publishEvent(new SimpleEvent<>(type, content));
}
public , S> void publishEvent(final Event event) {
log.debug("Publish event {} - {}", event.type(), event.content());
List> eventTypeListeners =
this.listeners.get(new ComparableEventType<>((Class) event.type().getClass()));
if (eventTypeListeners != null && !eventTypeListeners.isEmpty()) {
eventTypeListeners
.stream()
.filter(wrapper -> wrapper.events().contains(event.type()))
.forEach(wrapper -> ((EventListenerSubscription) wrapper).eventListener().onEvent(event));
}
}
public > void subscribeForEvents(EventListener eventListener, T... eventTypes) {
if (eventTypes.length > 0) {
Class eventTypeClass = (Class) eventTypes[0].getClass();
EnumSet eventTypesSet = EnumSet.of(eventTypes[0], eventTypes);
addEventListener(eventListener, eventTypeClass, eventTypesSet);
}
}
public > void subscribeForEvents(EventListener eventListener, Class eventTypeClass) {
addEventListener(eventListener, eventTypeClass, EnumSet.allOf(eventTypeClass));
}
private > void addEventListener(
final EventListener eventListener,
final Class eventTypeClass,
final Set eventTypes
) {
log.debug("Register new listener {} for event type {}", eventListener.getClass().getSimpleName(), eventTypeClass);
this.listeners.compute(
new ComparableEventType<>(eventTypeClass),
(k, v) -> {
if (v == null) {
v = new CopyOnWriteArrayList<>();
}
v.add(new EventListenerSubscription<>(eventListener, eventTypes));
return v;
}
);
}
@Override
public > void unsubscribeForEvents(final EventListener eventListener, final Class eventTypesClass) {
removeEventListener(eventListener, eventTypesClass, EnumSet.allOf(eventTypesClass));
}
@Override
public > void unsubscribeForEvents(final EventListener eventListener, final T... eventTypes) {
if (eventTypes.length > 0) {
Class eventTypeClass = (Class) eventTypes[0].getClass();
EnumSet eventTypesSet = EnumSet.of(eventTypes[0], eventTypes);
removeEventListener(eventListener, eventTypeClass, eventTypesSet);
}
}
private > void removeEventListener(
final EventListener eventListener,
final Class eventTypeClass,
final Set eventTypes
) {
log.debug("Unregister listener {} for event type {}", eventListener.getClass().getSimpleName(), eventTypeClass);
this.listeners.computeIfPresent(
new ComparableEventType<>(eventTypeClass),
(k, v) -> {
Set> removedEventListener = new HashSet<>();
v
.stream()
.filter(eventListenerSubscription -> eventListenerSubscription.eventListener.equals(eventListener))
.forEach(eventListenerSubscription -> {
eventListenerSubscription.events.removeAll(eventTypes);
if (eventListenerSubscription.events.isEmpty()) {
removedEventListener.add(eventListenerSubscription);
}
});
for (EventListenerSubscription, ?> eventListenerSubscription : removedEventListener) {
v.remove(eventListenerSubscription);
}
if (v.isEmpty()) {
return null;
}
return v;
}
);
}
private record EventListenerSubscription, S>(EventListener eventListener, Set events) {}
private record ComparableEventType>(Class extends T> wrappedClass) implements Comparable> {
@Override
public int compareTo(ComparableEventType o) {
return wrappedClass.getCanonicalName().compareTo(o.wrappedClass.getCanonicalName());
}
@Override
public boolean equals(Object o) {
if (!(o instanceof ComparableEventType)) {
return false;
}
return compareTo((ComparableEventType) o) == 0;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy