From a3815f14f7f1a2f3fd332c4b60253fd51800155d Mon Sep 17 00:00:00 2001 From: ribeaudc <ribeaudc> Date: Mon, 20 Aug 2007 11:22:58 +0000 Subject: [PATCH] add: - Spring 'BeanPostProcessor' implementation for registering 'ChangeListener' coming from 'RoleBasedAccessController': SynchronizerPostProcessor change: - Extract 'IRolesManager' and 'DefaultRolesManager' from 'RoleBasedAccessController' - lets Spring create the timer for file watchers SVN: 1421 --- .../utilities/FileWatcherSynchronizer.java | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/FileWatcherSynchronizer.java b/common/source/java/ch/systemsx/cisd/common/utilities/FileWatcherSynchronizer.java index 3273aed3a3c..a41eb295163 100644 --- a/common/source/java/ch/systemsx/cisd/common/utilities/FileWatcherSynchronizer.java +++ b/common/source/java/ch/systemsx/cisd/common/utilities/FileWatcherSynchronizer.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimerTask; +import java.util.WeakHashMap; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -35,8 +36,9 @@ import ch.systemsx.cisd.common.logging.LogFactory; * Kind of <code>FileWatcher</code> extension that allow registration of multiple <code>ChangeListener</code> for * one file watched. * <p> - * You can use this class as <i>singleton</i> calling {@link #getInstance()} or you may instance it with a constructor. - * Note that access to this class is <i>synchronized</i>. + * You can use this class as <i>singleton</i> calling {@link #getInstance()} or you may instance it with a constructor.<br /> + * Note that access to this class is <i>synchronized</i> and that this class internally uses a {@link WeakHashMap} to + * store the registered <code>ChangeListener</code>s. * </p> * * @author Christian Ribeaud @@ -44,6 +46,8 @@ import ch.systemsx.cisd.common.logging.LogFactory; public final class FileWatcherSynchronizer extends TimerTask { + private static final ChangeListener[] LISTENER_EMPTY_ARRAY = new ChangeListener[0]; + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, FileWatcherSynchronizer.class); @@ -68,6 +72,15 @@ public final class FileWatcherSynchronizer extends TimerTask return instance; } + private final synchronized void fireStateChanged(FileWatcher fileWatcher) + { + final ChangeEvent event = new ChangeEvent(fileWatcher.getFileToWatch()); + for (ChangeListener listener : fileWatcherListeners.get(fileWatcher)) + { + listener.stateChanged(event); + } + } + public final synchronized void addChangeListener(final File file, final ChangeListener changeListener) { FileWatcher fileWatcher = fileWatchers.get(file); @@ -102,7 +115,7 @@ public final class FileWatcherSynchronizer extends TimerTask if (operationLog.isDebugEnabled()) { operationLog.debug(String.format( - "A new listener has been registered for file '%s'. Currently %d listeners registered.", file, + "A new listener has been registered for file '%s'. Currently %d listener(s) registered.", file, listeners.size())); } } @@ -120,21 +133,44 @@ public final class FileWatcherSynchronizer extends TimerTask return; } listeners.remove(changeListener); + int size = listeners.size(); if (operationLog.isDebugEnabled()) { operationLog.debug(String.format( - "A listener for file '%s' has been removed. Currently %d listeners registered.", file, listeners - .size())); + "A listener for file '%s' has been removed. Currently %d listener(s) registered.", file, size)); + } + if (size == 0) + { + fileWatchers.remove(file); } } - private final synchronized void fireStateChanged(FileWatcher fileWatcher) + /** + * For given <var>file</var> returns the registered <code>ChangeListener</code>s. + * + * @return <code>null</code> if given <var>file</var> is unknown or if no <code>ChangeListener</code> could be + * found for given <var>file</var>. + */ + public final synchronized ChangeListener[] getChangeListeners(final File file) { - final ChangeEvent event = new ChangeEvent(fileWatcher.getFileToWatch()); - for (ChangeListener listener : fileWatcherListeners.get(fileWatcher)) + FileWatcher fileWatcher = fileWatchers.get(file); + if (fileWatcher == null) { - listener.stateChanged(event); + return null; + } + List<ChangeListener> listeners = fileWatcherListeners.get(fileWatcher); + if (listeners == null) + { + return null; } + return listeners.toArray(LISTENER_EMPTY_ARRAY); + } + + /** Clears the <code>Map</code>s used internally. */ + public final synchronized void destroy() + { + fileWatcherListeners.clear(); + fileWatchers.clear(); } // -- GitLab