From d7c08bc4ca91daf7f2c6c7a728055f41ebd8889f Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Tue, 30 Dec 2008 16:43:37 +0000 Subject: [PATCH] * add simple Timer * refactoring --- .../BackgroundFileTransferablePolicy.java | 9 +- .../web/OpenSubtitlesSubtitleClient.java | 77 ++------------- .../tuned/DefaultThreadFactory.java | 2 - source/net/sourceforge/tuned/Timer.java | 94 +++++++++++++++++++ 4 files changed, 108 insertions(+), 74 deletions(-) create mode 100644 source/net/sourceforge/tuned/Timer.java diff --git a/source/net/sourceforge/filebot/ui/transfer/BackgroundFileTransferablePolicy.java b/source/net/sourceforge/filebot/ui/transfer/BackgroundFileTransferablePolicy.java index 706f6912..c7487264 100644 --- a/source/net/sourceforge/filebot/ui/transfer/BackgroundFileTransferablePolicy.java +++ b/source/net/sourceforge/filebot/ui/transfer/BackgroundFileTransferablePolicy.java @@ -38,13 +38,13 @@ public abstract class BackgroundFileTransferablePolicy extends FileTransferab clear(); worker = new BackgroundWorker(files); - worker.addPropertyChangeListener(new BackgroundWorkerListener()); + worker.addPropertyChangeListener(backgroundWorkerListener); worker.execute(); } public synchronized boolean isActive() { - return (worker != null) && !worker.isDone(); + return worker != null && !worker.isDone(); } @@ -108,8 +108,7 @@ public abstract class BackgroundFileTransferablePolicy extends FileTransferab } } - - private class BackgroundWorkerListener extends SwingWorkerPropertyChangeAdapter { + private final PropertyChangeListener backgroundWorkerListener = new SwingWorkerPropertyChangeAdapter() { @Override public void started(PropertyChangeEvent evt) { @@ -121,7 +120,7 @@ public abstract class BackgroundFileTransferablePolicy extends FileTransferab public void done(PropertyChangeEvent evt) { propertyChangeSupport.firePropertyChange(LOADING_PROPERTY, true, false); } - } + }; private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); diff --git a/source/net/sourceforge/filebot/web/OpenSubtitlesSubtitleClient.java b/source/net/sourceforge/filebot/web/OpenSubtitlesSubtitleClient.java index 53408cd0..2bb06dac 100644 --- a/source/net/sourceforge/filebot/web/OpenSubtitlesSubtitleClient.java +++ b/source/net/sourceforge/filebot/web/OpenSubtitlesSubtitleClient.java @@ -3,11 +3,9 @@ package net.sourceforge.filebot.web; import java.net.URI; -import java.util.Collection; import java.util.List; import java.util.Locale; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -15,17 +13,16 @@ import javax.swing.Icon; import net.sourceforge.filebot.FileBotUtil; import net.sourceforge.filebot.ResourceManager; +import net.sourceforge.tuned.Timer; /** - * {@link SubtitleClient} for OpenSubtitles. + * SubtitleClient for OpenSubtitles. */ public class OpenSubtitlesSubtitleClient implements SubtitleClient { private final OpenSubtitlesClient client = new OpenSubtitlesClient(String.format("%s v%s", FileBotUtil.getApplicationName(), FileBotUtil.getApplicationVersion())); - private final LogoutTimer logoutTimer = new LogoutTimer(); - @Override public String getName() { @@ -44,19 +41,16 @@ public class OpenSubtitlesSubtitleClient implements SubtitleClient { public List search(String searchterm) throws Exception { login(); - List result = client.searchMoviesOnIMDB(searchterm); - return result; + return (List) client.searchMoviesOnIMDB(searchterm); } @SuppressWarnings("unchecked") @Override - public Collection getSubtitleList(SearchResult searchResult, Locale language) throws Exception { + public List getSubtitleList(SearchResult searchResult, Locale language) throws Exception { login(); - int imdbId = ((MovieDescriptor) searchResult).getImdbId(); - - return (Collection) client.searchSubtitles(imdbId, language); + return (List) client.searchSubtitles(((MovieDescriptor) searchResult).getImdbId(), language); } @@ -69,81 +63,30 @@ public class OpenSubtitlesSubtitleClient implements SubtitleClient { private synchronized void login() throws Exception { if (!client.isLoggedOn()) { client.loginAnonymous(); - Runtime.getRuntime().addShutdownHook(logoutShutdownHook); } - logoutTimer.restart(); + logoutTimer.set(12, TimeUnit.MINUTES, true); } private synchronized void logout() { - logoutTimer.stop(); + logoutTimer.cancel(); if (client.isLoggedOn()) { try { client.logout(); } catch (Exception e) { Logger.getLogger("global").log(Level.SEVERE, "Exception while deactivating session", e); - } finally { - try { - Runtime.getRuntime().removeShutdownHook(logoutShutdownHook); - } catch (IllegalStateException e) { - // shutdown in progress - } } } } - private final Thread logoutShutdownHook = new Thread() { + private final Timer logoutTimer = new Timer() { @Override public void run() { logout(); } + }; - - - private class LogoutTimer { - - private static final long LOGOUT_DELAY = 12 * 60 * 1000; // 12 minutes - - private Timer daemon = null; - private LogoutTimerTask currentTimerTask = null; - - - public synchronized void restart() { - if (daemon == null) { - daemon = new Timer(getClass().getName(), true); - } - - if (currentTimerTask != null) { - currentTimerTask.cancel(); - } - - currentTimerTask = new LogoutTimerTask(); - daemon.schedule(currentTimerTask, LOGOUT_DELAY); - } - - - public synchronized void stop() { - if (daemon == null) - return; - - currentTimerTask.cancel(); - currentTimerTask = null; - - daemon.cancel(); - daemon = null; - } - - - private class LogoutTimerTask extends TimerTask { - - @Override - public void run() { - logout(); - }; - }; - } - } diff --git a/source/net/sourceforge/tuned/DefaultThreadFactory.java b/source/net/sourceforge/tuned/DefaultThreadFactory.java index b6dd5185..a3e9c583 100644 --- a/source/net/sourceforge/tuned/DefaultThreadFactory.java +++ b/source/net/sourceforge/tuned/DefaultThreadFactory.java @@ -27,8 +27,6 @@ public class DefaultThreadFactory implements ThreadFactory { public DefaultThreadFactory(String groupName, int priority, boolean daemon) { group = new ThreadGroup(groupName); - group.setDaemon(daemon); - group.setMaxPriority(priority); this.daemon = daemon; this.priority = priority; diff --git a/source/net/sourceforge/tuned/Timer.java b/source/net/sourceforge/tuned/Timer.java new file mode 100644 index 00000000..0c6b137b --- /dev/null +++ b/source/net/sourceforge/tuned/Timer.java @@ -0,0 +1,94 @@ + +package net.sourceforge.tuned; + + +import java.util.concurrent.RunnableScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + + +public abstract class Timer implements Runnable { + + private final ScheduledThreadPoolExecutor executor; + + private RunnableScheduledFuture scheduledFuture; + private Thread shutdownHook; + + + public Timer() { + executor = new ScheduledThreadPoolExecutor(1); + executor.setKeepAliveTime(200, TimeUnit.MILLISECONDS); + executor.allowCoreThreadTimeOut(true); + } + + + public synchronized void set(long delay, TimeUnit unit, boolean runBeforeShutdown) { + removeScheduledFuture(); + + Runnable r = this; + + if (runBeforeShutdown) { + addShutdownHook(); + + // remove shutdown hook after execution + r = new Runnable() { + + @Override + public void run() { + try { + Timer.this.run(); + } finally { + removeShutdownHook(); + } + } + }; + } else { + // remove existing shutdown hook, if any + removeShutdownHook(); + } + + scheduledFuture = (RunnableScheduledFuture) executor.schedule(r, delay, unit); + } + + + public synchronized void cancel() { + removeScheduledFuture(); + removeShutdownHook(); + } + + + private synchronized void removeScheduledFuture() { + if (scheduledFuture != null) { + try { + scheduledFuture.cancel(false); + executor.remove(scheduledFuture); + } finally { + scheduledFuture = null; + } + } + } + + + private synchronized void addShutdownHook() { + if (shutdownHook == null) { + shutdownHook = new Thread(this); + Runtime.getRuntime().addShutdownHook(shutdownHook); + } + } + + + private synchronized void removeShutdownHook() { + if (shutdownHook != null) { + try { + if (shutdownHook != Thread.currentThread()) { + // can't remove shutdown hooks anymore, once runtime is shutting down, + // so don't remove the shutdown hook, if we are running on the shutdown hook + Runtime.getRuntime().removeShutdownHook(shutdownHook); + } + } finally { + shutdownHook = null; + } + } + } + +}