package org.infinispan.commons.api.functional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.infinispan.commons.api.functional.EntryView.ReadEntryView;
import org.infinispan.commons.util.Experimental;
/**
* Holder class for functional listener definitions.
*
* @since 8.0
*/
@Experimental
public final class Listeners {
private Listeners() {
// Cannot be instantiated, it's just a holder class
}
/**
* Read-write listeners enable users to register listeners for cache
* entry created, modified and removed events, and also register listeners
* for any cache entry write events.
*
* <p>Entry created, modified and removed events can only be fired when these
* originate on a read-write functional map, since this is the only one
* that guarantees that the previous value has been read, and hence the
* differentiation between create, modified and removed can be fully
* guaranteed.
*
* @since 8.0
*/
@Experimental
public interface ReadWriteListeners<K, V> extends WriteListeners<K, V> {
/**
* Add a create event specific listener by passing in a
* {@link Consumer} to be called back each time a new cache entry is
* created, passing in a {@link ReadEntryView} of that new entry.
*
* <p>This method is shortcut for users who are only interested in
* create events. If interested in multiple event types, calling
* {@link #add(ReadWriteListener)} is recommended instead.
*
* @param f operation to be called each time a new cache entry is created
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable onCreate(Consumer<ReadEntryView<K, V>> f);
/**
* Add a modify/update event specific listener by passing in a
* {@link BiConsumer} to be called back each time an entry is
* modified or updated, passing in a {@link ReadEntryView} of the
* previous entry as first parameter, and a {@link ReadEntryView} of the
* new value as second parameter.
*
* <p>This method is shortcut for users who are only interested in
* update events. If interested in multiple event types, calling
* {@link #add(ReadWriteListener)} is recommended instead.
*
* @param f operation to be called each time a new cache entry is modified or updated,
* with the first parameter the {@link ReadEntryView} of the previous
* entry value, and the second parameter the new {@link ReadEntryView}
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable onModify(BiConsumer<ReadEntryView<K, V>, ReadEntryView<K, V>> f);
/**
* Add a remove event specific listener by passing in a
* {@link Consumer} to be called back each time an entry is
* removed, passing in the {@link ReadEntryView} of the removed entry.
*
* <p>This method is shortcut for users who are only interested in
* remove events. If interested in multiple event types, calling
* {@link #add(ReadWriteListener)} is recommended instead.
*
* @param f operation to be called each time a new cache entry is removed,
* with the old cached entry's {@link ReadEntryView} as parameter.
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable onRemove(Consumer<ReadEntryView<K, V>> f);
/**
* Add a read-write listener, and return an {@link AutoCloseable}
* instance that can be used to remove the listener registration.
*
* @param l the read-write functional map event listener
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable add(ReadWriteListener<K, V> l);
/**
* Read-write listener
*/
interface ReadWriteListener<K, V> {
/**
* Entry created event callback that receives a {@link ReadEntryView}
* of the created entry.
*
* @param created created entry view
*/
default void onCreate(ReadEntryView<K, V> created) {}
/**
* Entry modify/update event callback that receives {@link ReadEntryView}
* of the previous entry as first parameter, and the {@link ReadEntryView}
* of the new entry.
*
* @param before previous entry view
* @param after new entry view
*/
default void onModify(ReadEntryView<K, V> before, ReadEntryView<K, V> after) {}
/**
* Entry removed event callback that receives a {@link ReadEntryView}
* of the removed entry.
*
* @param removed removed entry view
*/
default void onRemove(ReadEntryView<K, V> removed) {}
}
}
/**
* Write listeners enable user to register listeners for any cache entry
* write events that happen in either a read-write or write-only
* functional map.
*
* <p>Listeners for write events cannot distinguish between cache entry
* created and cache entry modify/update events because they don't have
* access to the previous value. All they know is that a new non-null
* entry has been written.
*
* <p>However, write event listeners can distinguish between entry removals
* and cache entry create/modify-update events because they can query
* what the new entry's value via {@link ReadEntryView#find()}.
*
* @since 8.0
*/
@Experimental
public interface WriteListeners<K, V> {
/**
* Add a write event listener by passing in a {@link Consumer} to be
* called each time a cache entry is created, modified/updated or
* removed.
*
* <p>For created or modified/updated events, the
* {@link ReadEntryView} passed in will represent the newly stored
* entry, hence implementations will not be available to differentiate
* between created events vs modified/updated events.
*
* <p>For removed events, {@link ReadEntryView} passed in will represent
* an empty entry view, hence {@link ReadEntryView#find()} will return
* an empty {@link java.util.Optional} instance, and
* {@link ReadEntryView#get()} will throw
* {@link java.util.NoSuchElementException}.
*
* @param f operation to be called each time a cache entry is written
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable onWrite(Consumer<ReadEntryView<K, V>> f);
/**
* Add a write-only listener, and return an {@link AutoCloseable}
* instance that can be used to remove the listener registration.
*
* @param l the write-only functional map event listener
* @return an {@link AutoCloseable} instance that can be used to
* unregister the listener
*/
AutoCloseable add(WriteListener<K, V> l);
/**
* Write-only listener.
*
* @since 8.0
*/
@Experimental
interface WriteListener<K, V> {
/**
* Entry write event callback that receives a {@link ReadEntryView}
* of the written entry.
*
* <p>For created or modified/updated events, the
* {@link ReadEntryView} passed in will represent the newly stored
* entry, hence implementations will not be available to differentiate
* between created events vs modified/updated events.
*
* <p>For removed events, {@link ReadEntryView} passed in will represent
* an empty entry view, hence {@link ReadEntryView#find()} will return
* an empty {@link java.util.Optional} instance, and
* {@link ReadEntryView#get()} will throw
* {@link java.util.NoSuchElementException}.
*
* @param write written entry view
*/
void onWrite(ReadEntryView<K, V> write);
}
}
}