/* * Copyright Terracotta, Inc. * * 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 org.ehcache.transactions.xa.internal; import org.ehcache.event.EventType; import org.ehcache.impl.internal.events.StoreEventImpl; import org.ehcache.core.spi.store.events.StoreEvent; import org.ehcache.core.spi.store.events.StoreEventFilter; import org.ehcache.core.spi.store.events.StoreEventListener; import org.ehcache.core.spi.store.events.StoreEventSource; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static org.ehcache.impl.internal.events.StoreEvents.createEvent; import static org.ehcache.impl.internal.events.StoreEvents.updateEvent; /** * StoreEventSourceWrapper */ class StoreEventSourceWrapper<K, V> implements StoreEventSource<K, V> { private final StoreEventSource<K, SoftLock<V>> underlying; private final Map<StoreEventListener<K, V>, StoreEventListener<K, SoftLock<V>>> listenersMap = new ConcurrentHashMap<StoreEventListener<K, V>, StoreEventListener<K, SoftLock<V>>>(10); StoreEventSourceWrapper(StoreEventSource<K, SoftLock<V>> underlying) { this.underlying = underlying; underlying.addEventFilter(new StoreEventFilter<K, SoftLock<V>>() { @Override public boolean acceptEvent(EventType type, K key, SoftLock<V> oldValue, SoftLock<V> newValue) { if (newValue != null) { return newValue.getOldValue() != null; } else if (oldValue != null) { return oldValue.getOldValue() != null; } return false; } }); } @Override public void addEventListener(final StoreEventListener<K, V> eventListener) { StoreEventListenerWrapper<K, V> listenerWrapper = new StoreEventListenerWrapper<K, V>(eventListener); listenersMap.put(eventListener, listenerWrapper); underlying.addEventListener(listenerWrapper); } @Override public void removeEventListener(StoreEventListener<K, V> eventListener) { StoreEventListener<K, SoftLock<V>> listenerWrapper = listenersMap.get(eventListener); if (listenerWrapper != null) { underlying.removeEventListener(listenerWrapper); } } @Override public void addEventFilter(final StoreEventFilter<K, V> eventFilter) { underlying.addEventFilter(new StoreEventFilter<K, SoftLock<V>>() { @Override public boolean acceptEvent(EventType type, K key, SoftLock<V> oldValue, SoftLock<V> newValue) { V unwrappedOldValue = null; V unwrappedNewValue = null; if (oldValue != null) { unwrappedOldValue = oldValue.getOldValue(); } if (newValue != null) { unwrappedNewValue = newValue.getOldValue(); } if (unwrappedNewValue == null && unwrappedOldValue == null) { return false; } return eventFilter.acceptEvent(type, key, unwrappedOldValue, unwrappedNewValue); } }); } @Override public void setEventOrdering(boolean ordering) { underlying.setEventOrdering(ordering); } @Override public boolean isEventOrdering() { return underlying.isEventOrdering(); } private static class StoreEventListenerWrapper<K, V> implements StoreEventListener<K, SoftLock<V>> { private final StoreEventListener<K, V> wrappedOne; private StoreEventListenerWrapper(StoreEventListener<K, V> wrappedOne) { if (wrappedOne == null) { throw new NullPointerException("Wrapped StoreEventListener cannot be null"); } this.wrappedOne = wrappedOne; } @Override public void onEvent(StoreEvent<K, SoftLock<V>> event) { StoreEvent<K, V> eventToPropagate = null; switch (event.getType()) { case CREATED: eventToPropagate = createEvent(event.getKey(), event.getNewValue().getOldValue()); break; case UPDATED: eventToPropagate = updateEvent(event.getKey(), event.getOldValue().getOldValue(), event.getNewValue() .getOldValue()); break; case REMOVED: case EXPIRED: case EVICTED: eventToPropagate = new StoreEventImpl<K, V>(event.getType(), event.getKey(), event.getOldValue().getOldValue(), null); break; } wrappedOne.onEvent(eventToPropagate); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; StoreEventListenerWrapper<?, ?> that = (StoreEventListenerWrapper<?, ?>) o; return wrappedOne.equals(that.wrappedOne); } @Override public int hashCode() { return wrappedOne.hashCode(); } } }