1 package net.suberic.pooka.thread; 2 import net.suberic.pooka.FolderInfo; 3 import net.suberic.pooka.Pooka; 4 import net.suberic.util.thread.*; 5 import javax.mail.*; 6 import java.util.*; 7 import java.util.logging.*; 8 import java.awt.event.ActionEvent ; 9 10 15 public class FolderTracker extends Thread { 16 private Vector mUpdateInfos = new Vector(); 17 private CheckFolderAction mAction = new CheckFolderAction(); 18 private long mTrackerNextUpdateTime = -1; 19 private boolean mStopped = false; 20 private Logger mLogger = null; 21 22 25 private class UpdateInfo { 26 FolderInfo folder; 28 long updateCheckMilliseconds; 30 long nextFolderUpdate; 32 boolean updateRunning = false; 34 35 39 public UpdateInfo(FolderInfo info, long updateCheck) { 40 folder = info; 41 updateCheckMilliseconds = updateCheck; 42 nextFolderUpdate = Calendar.getInstance().getTime().getTime() + updateCheckMilliseconds; 43 } 44 45 48 public void update() { 49 getLogger().fine("creating update action for folder " + folder.getFolderID()); 50 updateRunning = true; 51 folder.getFolderThread().addToQueue(getAction(), new ActionEvent (this, 1, "folder-check - " + folder.getFolderID()), ActionThread.PRIORITY_LOW); 52 } 53 54 57 public void newUpdateTime() { 58 updateRunning = false; 59 nextFolderUpdate = Calendar.getInstance().getTime().getTime() + updateCheckMilliseconds; 60 getLogger().finer("calculating new update time for " + folder.getFolderID() + ": " + nextFolderUpdate); 61 updateTrackerNextTime(nextFolderUpdate); 62 } 63 64 67 public boolean shouldUpdate(long currentTime) { 68 return (! updateRunning && nextFolderUpdate <= currentTime) ; 69 } 70 71 74 public long getNextFolderUpdate() { return nextFolderUpdate; } 75 76 79 public FolderInfo getFolderInfo() { return folder; } 80 81 85 public boolean isUpdateRunning() { return updateRunning; } 86 87 } 89 90 93 public FolderTracker() { 94 super("Folder Tracker thread"); 95 this.setPriority(1); 96 } 97 98 100 103 public void addFolder(FolderInfo newFolder) { 104 if (newFolder == null) 105 return ; 106 107 getLogger().fine("adding folder " + newFolder.getFolderID()); 108 long updateCheckMilliseconds; 109 String updateString = Pooka.getProperty("Pooka.updateCheckMilliseconds", "60000"); 110 111 if (newFolder.getParentStore() != null) { 112 updateString = Pooka.getProperty(newFolder.getFolderProperty() + ".updateCheckSeconds", Pooka.getProperty(newFolder.getParentStore().getStoreProperty() + ".updateCheckSeconds", Pooka.getProperty("Pooka.updateCheckSeconds", "300"))); 113 } 114 try { 115 updateCheckMilliseconds = Long.parseLong(updateString) *1000; 116 } catch (Exception e) { 117 updateCheckMilliseconds = 60000; 118 } 119 120 UpdateInfo info = new UpdateInfo(newFolder, updateCheckMilliseconds); 121 mUpdateInfos.add(info); 122 updateTrackerNextTime(info.getNextFolderUpdate()); 123 } 124 125 128 public void removeFolder(FolderInfo folder) { 129 if (folder == null) 130 return; 131 132 getLogger().fine("removing folder " + folder.getFolderID() + " from tracker."); 133 134 for (int i = 0 ; i < mUpdateInfos.size() ; i++) 135 if (((UpdateInfo) mUpdateInfos.elementAt(i)).folder == folder) 136 mUpdateInfos.removeElementAt(i); 137 } 138 139 141 143 148 public synchronized void updateTrackerNextTime(long pTime) { 149 getLogger().finer("updating tracker next time with new value " + pTime + ", old value " + mTrackerNextUpdateTime); 150 if (pTime < mTrackerNextUpdateTime) { 151 mTrackerNextUpdateTime = pTime; 152 getLogger().finer("new time is newer than old time; interrupting thread."); 153 interrupt(); 154 } 155 } 156 157 162 public synchronized long calculateNextUpdateTime(long currentTime) { 163 getLogger().finer("calculating next update time."); 164 165 long nextTime = -1; 166 Iterator iter = mUpdateInfos.iterator(); 167 while (iter.hasNext()) { 168 UpdateInfo current = (UpdateInfo) iter.next(); 169 if (! current.isUpdateRunning()) { 170 if (nextTime == -1) 171 nextTime = current.getNextFolderUpdate(); 172 else 173 nextTime = Math.min(nextTime, current.getNextFolderUpdate()); 174 } 175 } 176 177 if (nextTime == -1) 178 nextTime = currentTime + 120000; 179 180 mTrackerNextUpdateTime = nextTime; 181 getLogger().finer("new next update time: " + mTrackerNextUpdateTime); 182 183 return mTrackerNextUpdateTime; 184 } 185 186 188 190 194 public void run() { 195 while (true && ! mStopped) { 196 try { 197 getLogger().fine("running folder tracker update."); 198 199 long currentTime = Calendar.getInstance().getTime().getTime(); 200 updateFolders(currentTime); 201 long sleepTime = calculateNextUpdateTime(currentTime) - currentTime; 202 if (sleepTime > 0) { 203 getLogger().finer("sleeping for " + sleepTime + " milliseconds."); 204 205 sleep(sleepTime); 206 } else { 207 getLogger().finer("sleep time is negative; not sleeping."); 208 } 209 } catch (InterruptedException ie) { 210 getLogger().finer("caught InterruptedException."); 212 } 213 } 214 215 getLogger().fine("Stopped. Shutting down Folder Tracker."); 216 } 217 218 222 public void updateFolders(long currentTime) { 223 for (int i = 0; i < mUpdateInfos.size(); i++) { 224 UpdateInfo info = (UpdateInfo)mUpdateInfos.elementAt(i); 225 if (info.shouldUpdate(currentTime)) 226 info.update(); 227 } 228 } 229 230 232 234 237 public void setStopped(boolean pStopped) { 238 mStopped = pStopped; 239 getLogger().fine("setting FolderTracker stopped to " + mStopped); 240 if (mStopped == true) 241 interrupt(); 242 } 243 244 246 248 251 public javax.swing.Action getAction() { 252 return mAction; 253 } 254 255 259 public class CheckFolderAction extends javax.swing.AbstractAction { 260 public CheckFolderAction() { 261 super("folder-check"); 262 } 263 264 public void actionPerformed(java.awt.event.ActionEvent e) { 265 UpdateInfo info = (UpdateInfo) e.getSource(); 266 try { 267 getLogger().fine("running checkFolder on " + info.getFolderInfo().getFolderID()); 268 info.getFolderInfo().checkFolder(); 269 } catch (MessagingException me) { 270 if (getLogger().isLoggable(Level.FINE)) { 272 getLogger().fine("caught exception checking folder " + info.getFolderInfo().getFolderID() + ": " + me); 273 me.printStackTrace(); 274 } 275 } finally { 276 info.newUpdateTime(); 277 } 278 } 279 } 280 281 283 285 288 public Logger getLogger() { 289 if (mLogger == null) { 290 mLogger = java.util.logging.Logger.getLogger("Pooka.debug.folderTracker"); 291 } 292 293 return mLogger; 294 } 295 } 296 | Popular Tags |