use of org.infinispan.stream.impl.intops.object.MapOperation in project infinispan by infinispan.
the class CacheNotifierImpl method addFilteredListenerInternal.
private <C> CompletionStage<Void> addFilteredListenerInternal(Object listener, DataConversion keyDataConversion, DataConversion valueDataConversion, CacheEventFilter<? super K, ? super V> filter, CacheEventConverter<? super K, ? super V, C> converter, Set<Class<? extends Annotation>> filterAnnotations, boolean useStorageFormat) {
final Listener l = testListenerClassValidity(listener.getClass());
final UUID generatedId = Util.threadLocalRandomUUID();
final CacheMode cacheMode = config.clustering().cacheMode();
FilterIndexingServiceProvider indexingProvider = null;
boolean foundMethods = false;
// We use identity for null as this means it was invoked by a non encoder cache
DataConversion keyConversion = keyDataConversion == null ? DataConversion.IDENTITY_KEY : keyDataConversion;
DataConversion valueConversion = valueDataConversion == null ? DataConversion.IDENTITY_VALUE : valueDataConversion;
if (filter instanceof IndexedFilter) {
indexingProvider = findIndexingServiceProvider((IndexedFilter) filter);
if (indexingProvider != null) {
DelegatingCacheInvocationBuilder builder = new DelegatingCacheInvocationBuilder(indexingProvider);
adjustCacheInvocationBuilder(builder, filter, converter, filterAnnotations, l, useStorageFormat, generatedId, keyConversion, valueConversion, null);
foundMethods = validateAndAddFilterListenerInvocations(listener, builder, filterAnnotations);
builder.registerListenerInvocations();
}
}
if (indexingProvider == null) {
CacheInvocationBuilder builder = new CacheInvocationBuilder();
adjustCacheInvocationBuilder(builder, filter, converter, filterAnnotations, l, useStorageFormat, generatedId, keyConversion, valueConversion, null);
foundMethods = validateAndAddFilterListenerInvocations(listener, builder, filterAnnotations);
}
CompletionStage<Void> stage = CompletableFutures.completedNull();
if (foundMethods && l.clustered()) {
if (l.observation() == Listener.Observation.PRE) {
throw CONTAINER.clusterListenerRegisteredWithOnlyPreEvents(listener.getClass());
} else if (cacheMode.isInvalidation()) {
throw new UnsupportedOperationException("Cluster listeners cannot be used with Invalidation Caches!");
} else if (clusterListenerOnPrimaryOnly()) {
clusterListenerIDs.put(listener, generatedId);
// This way we only retrieve members of the cache itself
Address ourAddress = rpcManager.getAddress();
List<Address> members = rpcManager.getMembers();
// If we are the only member don't even worry about sending listeners
if (members != null && members.size() > 1) {
stage = registerClusterListeners(members, generatedId, ourAddress, filter, converter, l, listener, keyDataConversion, valueDataConversion, useStorageFormat);
}
}
}
// If we have a segment listener handler, it means we have to do initial state
QueueingSegmentListener<K, V, ? extends Event<K, V>> handler = segmentHandler.remove(generatedId);
if (handler != null) {
if (log.isTraceEnabled()) {
log.tracef("Listener %s requests initial state for cache", generatedId);
}
Collection<IntermediateOperation<?, ?, ?, ?>> intermediateOperations = new ArrayList<>();
MediaType storage = valueConversion.getStorageMediaType();
MediaType keyReq = keyConversion.getRequestMediaType();
MediaType valueReq = valueConversion.getRequestMediaType();
AdvancedCache advancedCache = cache.running();
DataConversion chainedKeyDataConversion = advancedCache.getKeyDataConversion();
DataConversion chainedValueDataConversion = advancedCache.getValueDataConversion();
if (keyReq != null && valueReq != null) {
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(keyReq);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(valueReq);
}
boolean hasFilter = false;
MediaType filterMediaType = null;
if (filter != null) {
hasFilter = true;
filterMediaType = useStorageFormat ? null : filter.format();
if (filterMediaType == null) {
// iterate in the storage format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(storage);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(storage);
} else {
// iterate in the filter format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(filterMediaType);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(filterMediaType);
}
}
if (converter != null) {
hasFilter = true;
filterMediaType = useStorageFormat ? null : converter.format();
if (filterMediaType == null) {
// iterate in the storage format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(storage);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(storage);
} else {
// iterate in the filter format
chainedKeyDataConversion = chainedKeyDataConversion.withRequestMediaType(filterMediaType);
chainedValueDataConversion = chainedValueDataConversion.withRequestMediaType(filterMediaType);
}
}
if (!Objects.equals(chainedKeyDataConversion, keyDataConversion) || !Objects.equals(chainedValueDataConversion, valueDataConversion)) {
componentRegistry.wireDependencies(chainedKeyDataConversion, false);
componentRegistry.wireDependencies(chainedValueDataConversion, false);
intermediateOperations.add(new MapOperation<>(EncoderEntryMapper.newCacheEntryMapper(chainedKeyDataConversion, chainedValueDataConversion, entryFactory)));
}
if (filter instanceof CacheEventFilterConverter && (filter == converter || converter == null)) {
intermediateOperations.add(new MapOperation<>(CacheFilters.converterToFunction(new CacheEventFilterConverterAsKeyValueFilterConverter<>((CacheEventFilterConverter<?, ?, ?>) filter))));
intermediateOperations.add(new FilterOperation<>(CacheFilters.notNullCacheEntryPredicate()));
} else {
if (filter != null) {
intermediateOperations.add(new FilterOperation<>(CacheFilters.predicate(new CacheEventFilterAsKeyValueFilter<>(filter))));
}
if (converter != null) {
intermediateOperations.add(new MapOperation<>(CacheFilters.function(new CacheEventConverterAsConverter<>(converter))));
}
}
boolean finalHasFilter = hasFilter;
MediaType finalFilterMediaType = filterMediaType;
Function<Object, Object> kc = k -> {
if (!finalHasFilter)
return k;
if (finalFilterMediaType == null || useStorageFormat || keyReq == null) {
return keyDataConversion.fromStorage(k);
}
return encoderRegistry.convert(k, finalFilterMediaType, keyDataConversion.getRequestMediaType());
};
Function<Object, Object> kv = v -> {
if (!finalHasFilter)
return v;
if (finalFilterMediaType == null || useStorageFormat || valueReq == null) {
return valueConversion.fromStorage(v);
}
return encoderRegistry.convert(v, finalFilterMediaType, valueConversion.getRequestMediaType());
};
stage = handlePublisher(stage, intermediateOperations, handler, generatedId, l, kc, kv);
}
return stage;
}
Aggregations