/*
* 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.jsr107;
import java.io.
Closeable;
import java.util.
Collections;
import java.util.
Map;
import java.util.concurrent.
ConcurrentHashMap;
import java.util.concurrent.atomic.
AtomicBoolean;
import javax.cache.configuration.
CacheEntryListenerConfiguration;
import org.ehcache.jsr107.internal.
Jsr107CacheLoaderWriter;
/**
* @author teck
*/
class
CacheResources<K, V> {
private final
Eh107Expiry<K, V>
expiryPolicy;
private final
Jsr107CacheLoaderWriter<? super K, V>
cacheLoaderWriter;
private final
Map<
CacheEntryListenerConfiguration<K, V>,
ListenerResources<K, V>>
listenerResources = new
ConcurrentHashMap<
CacheEntryListenerConfiguration<K, V>,
ListenerResources<K, V>>();
private final
AtomicBoolean closed = new
AtomicBoolean();
private final
String cacheName;
CacheResources(
String cacheName,
Jsr107CacheLoaderWriter<? super K, V>
cacheLoaderWriter,
Eh107Expiry<K, V>
expiry,
Map<
CacheEntryListenerConfiguration<K, V>,
ListenerResources<K, V>>
listenerResources) {
this.
cacheName =
cacheName;
this.
cacheLoaderWriter =
cacheLoaderWriter;
this.
expiryPolicy =
expiry;
this.
listenerResources.
putAll(
listenerResources);
}
CacheResources(
String cacheName,
Jsr107CacheLoaderWriter<? super K, V>
cacheLoaderWriter,
Eh107Expiry<K, V>
expiry) {
this(
cacheName,
cacheLoaderWriter,
expiry, new
ConcurrentHashMap<
CacheEntryListenerConfiguration<K, V>,
ListenerResources<K, V>>());
}
Eh107Expiry<K, V>
getExpiryPolicy() {
return
expiryPolicy;
}
Jsr107CacheLoaderWriter<? super K, V>
getCacheLoaderWriter() {
return
cacheLoaderWriter;
}
Map<
CacheEntryListenerConfiguration<K, V>,
ListenerResources<K, V>> getListenerResources() {
return
Collections.
unmodifiableMap(
listenerResources);
}
synchronized
ListenerResources<K, V> registerCacheEntryListener(
CacheEntryListenerConfiguration<K, V>
listenerConfig) {
checkClosed();
if (
listenerResources.
containsKey(
listenerConfig)) {
throw new
IllegalArgumentException("listener config already registered");
}
MultiCacheException mce = new
MultiCacheException();
ListenerResources<K, V>
rv =
ListenerResources.
createListenerResources(
listenerConfig,
mce);
mce.
throwIfNotEmpty();
listenerResources.
put(
listenerConfig,
rv);
return
rv;
}
private void
checkClosed() {
if (
closed.
get()) {
throw new
IllegalStateException("cache resources closed for cache [" +
cacheName + "]");
}
}
synchronized
ListenerResources<K, V> deregisterCacheEntryListener(
CacheEntryListenerConfiguration<K, V>
listenerConfig) {
checkClosed();
ListenerResources<K, V>
resources =
listenerResources.
remove(
listenerConfig);
if (
resources == null) {
return null;
}
MultiCacheException mce = new
MultiCacheException();
close(
resources,
mce);
mce.
throwIfNotEmpty();
return
resources;
}
synchronized void
closeResources(
MultiCacheException mce) {
if (
closed.
compareAndSet(false, true)) {
close(
expiryPolicy,
mce);
close(
cacheLoaderWriter,
mce);
for (
ListenerResources<K, V>
lr :
listenerResources.
values()) {
close(
lr,
mce);
}
}
}
boolean
isClosed() {
return
closed.
get();
}
static void
close(
Object obj,
MultiCacheException mce) {
if (
obj instanceof
Closeable) {
try {
((
Closeable)
obj).
close();
} catch (
Throwable t) {
mce.
addThrowable(
t);
}
}
}
}