/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU
* General Public License Version 3 only ("GPL").
* You may not use this file except in compliance with the License.
* You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html
* See the License for the specific language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*
*/
package org.jopendocument.util.cache;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* A watcher invalidates cache results when its data is modified.
*
* @param <K> cache key type.
* @param <D> source data type, eg SQLTable.
*/
abstract public class CacheWatcher<K, D> {
private final ICache<K, ?, D> c;
private final Set<K> keys;
private final D data;
protected CacheWatcher(ICache<K, ?, D> c, D data) {
this.c = c;
this.keys = new HashSet<K>();
this.data = data;
}
public final D getData() {
return this.data;
}
synchronized boolean isEmpty() {
return this.keys.isEmpty();
}
synchronized final void add(K key) {
this.keys.add(key);
}
synchronized final void remove(K key) {
this.keys.remove(key);
}
public final synchronized void die() {
this.dying();
this.clearCache();
}
protected void dying() {
}
protected final void clearCache() {
// synch on the cache since otherwise we take and release its lock on each iteration
// but keep ours all the time. Thus if another thread call a synchronized method of the
// cache inbetween an iteration and tries to access us, a deadlock occurs.
synchronized (this.c) {
synchronized (this) {
final Iterator<K> iter = this.keys.iterator();
while (iter.hasNext()) {
final K key = iter.next();
iter.remove();
this.c.clear(key);
}
}
}
}
}