1 18 package org.columba.core.scripting; 19 20 import java.io.File ; 21 import java.io.FileFilter ; 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 import java.util.Map ; 28 import java.util.Vector ; 29 import java.util.logging.Logger ; 30 import java.util.regex.Pattern ; 31 32 import org.columba.core.gui.scripting.ScriptManagerDocument; 33 import org.columba.core.scripting.config.BeanshellConfig; 34 import org.columba.core.scripting.config.OptionsObserver; 35 import org.columba.core.scripting.interpreter.InterpreterManager; 36 import org.columba.core.scripting.model.ColumbaScript; 37 38 50 public class FileObserverThread 51 extends Thread 52 implements OptionsObserver, 53 ScriptManagerDocument 54 { 55 56 private static final Logger LOG = Logger.getLogger(FileObserverThread.class.getName()); 57 58 private final BeanshellConfig config; 59 private final ScriptFileFilter fileFilter; 60 private final InterpreterManager interpreterManager; 61 private final List observers; 62 private Map <String ,ColumbaScript> scriptList; 63 64 private long lastExecution; 65 private int pollingInterval = -1; 66 private boolean finish = false; 67 68 private static FileObserverThread self = null; 69 70 private FileObserverThread() 71 { 72 73 config = BeanshellConfig.getInstance(); 74 fileFilter = new ScriptFileFilter(); 75 interpreterManager = new InterpreterManager(); 76 77 scriptList = new HashMap <String , ColumbaScript>(); 78 observers = new Vector (); 79 lastExecution = System.currentTimeMillis(); 80 81 pollingInterval = config.getOptions().getInternalPollingInterval(); 82 fileFilter.compileFilter(interpreterManager.getSupportedExtensions()); 83 84 } 85 86 public void setScriptList(Map scripts) 87 { 88 scriptList = scripts; 89 } 90 91 public void finish() 92 { 93 finish = true; 94 } 95 96 private synchronized void executeRefresh(boolean force) 97 { 98 List changedFiles = checkFiles(); 99 100 if (changedFiles.size() > 0) 101 execChangedFiles(changedFiles); 102 103 lastExecution = System.currentTimeMillis(); 104 105 } 106 107 public void run() 108 { 109 config.getOptions().addObserver(this); 110 111 while (!finish) 112 { 113 114 executeRefresh(false); 115 116 try 117 { 118 sleep(pollingInterval); 119 } 120 catch (InterruptedException ex) 121 {} 122 123 } 124 125 config.getOptions().removeObserver(this); 126 self = null; 127 } 128 129 private List checkFiles() 130 { 131 132 List changedFiles = new ArrayList (), 133 removedScripts = new ArrayList (), 134 addedScripts = new ArrayList (); 135 136 ColumbaScript script = null; 138 Map.Entry entry = null; 139 140 synchronized (scriptList) 141 { 142 143 for (Iterator itCurrent = scriptList.entrySet().iterator(); itCurrent.hasNext();) 144 { 145 entry = (Map.Entry ) itCurrent.next(); 146 script = (ColumbaScript) entry.getValue(); 147 148 LOG.fine("current script.name="+script.getName()); 149 LOG.fine("current script.path="+script.getPath()); 150 151 if (!script.exists()) 152 { 153 removedScripts.add(script); 155 itCurrent.remove(); 156 continue; 157 } 158 159 if (script.getLastModified() > lastExecution) 160 changedFiles.add(script); 161 162 } 163 164 165 File [] scripts = getNewScripts(); 166 LOG.fine("script file count="+scripts.length); 167 168 for (int i = 0; i < scripts.length; i++) 169 { 170 LOG.fine("script file="+scripts[i].getAbsolutePath()); 171 172 if (!scriptList.containsKey(scripts[i].getPath())) 173 { 174 script = new ColumbaScript(scripts[i]); 175 176 LOG.fine("added script.name="+script.getName()); 177 LOG.fine("added script.path="+script.getPath()); 178 179 changedFiles.add(script); 180 scriptList.put(scripts[i].getPath(), script); 181 addedScripts.add(script); 182 } 183 } 184 185 } 186 187 for (Iterator it = observers.iterator(); it.hasNext();) 188 { 189 190 IScriptsObserver obs = (IScriptsObserver) it.next(); 191 if (removedScripts.size() > 0) 192 obs.scriptsRemoved(removedScripts); 193 194 if (addedScripts.size() > 0) 195 obs.scriptsAdded(addedScripts); 196 197 if (changedFiles.size() > 0) 198 obs.scriptsChanged(changedFiles); 199 200 } 201 202 return changedFiles; 203 204 } 205 206 private File [] getNewScripts() 207 { 208 215 File configPath = config.getPath(); 216 if (!configPath.exists() || !configPath.isDirectory()) 217 { 218 LOG.warning("Scripts directory doesn't exist:" + configPath.getPath()); 219 return new File []{}; 220 } 221 222 LOG.fine("script search path="+configPath.getAbsolutePath()); 223 224 return configPath.listFiles(fileFilter); 225 } 226 227 private void execChangedFiles(List files) 228 { 229 for (Iterator it = files.iterator(); it.hasNext();) 230 interpreterManager.executeScript((ColumbaScript) it.next()); 231 } 232 233 private class ScriptFileFilter 234 implements FileFilter 235 { 236 237 private Pattern extensionPattern = null; 238 239 private String join(String [] values, char separator) 240 { 241 242 StringBuffer bf = new StringBuffer (256); 243 for (int i = 0; i < values.length; i++) 244 bf = bf.append(values[i] + separator); 245 246 if (bf.length() > 0) bf = bf.deleteCharAt(bf.length() - 1); 247 248 return bf.toString(); 249 250 } 251 252 public void compileFilter(String [] validExtensions) 253 { 254 extensionPattern = 255 Pattern.compile(".*\\.(".concat(join(validExtensions, '|')).concat(")$")); 256 LOG.fine("valid extensions pattern="+extensionPattern.toString()); 257 } 258 259 public boolean accept(File aPathname) 260 { 261 boolean accept = extensionPattern.matcher(aPathname.getPath()).matches(); 262 LOG.fine("accept="+aPathname.getAbsolutePath() + " -> "+accept); 263 264 return accept; 265 } 266 267 } 268 269 public void pollingIntervalChanged(int interval) 270 { 271 pollingInterval = interval; 272 } 273 274 public void pollingStateChanged(boolean enabled) 275 { 276 277 } 278 279 public static FileObserverThread getInstance() 280 { 281 if (self == null) 282 self = new FileObserverThread(); 283 284 return self; 285 } 286 287 public void addObserver(IScriptsObserver observer) 288 { 289 if (!observers.contains(observer)) observers.add(observer); 290 } 291 292 public void removeObserver(IScriptsObserver observer) 293 { 294 observers.remove(observer); 295 } 296 297 public List getScripts() 298 { 299 return new ArrayList <ColumbaScript>(scriptList.values()); 300 } 301 302 public void refreshScriptList() 303 { 304 executeRefresh(true); 305 } 306 307 public ColumbaScript getScript(String path) 308 { 309 return (ColumbaScript) scriptList.get(path); 310 } 311 312 public void removeScript(ColumbaScript[] scripts) 313 { 314 315 synchronized (scriptList) 316 { 317 318 for (int i = 0; i < scripts.length; i++) 319 { 320 321 322 LOG.fine("Removing script: " + scripts[i].getPath()); 323 324 if (scripts[i].exists()) scripts[i].deleteFromDisk(); 325 326 327 scriptList.remove(scripts[i].getPath()); 328 329 } 330 331 } 332 333 List removed = Arrays.asList(scripts); 334 for (Iterator it = observers.iterator(); it.hasNext();) 335 ((IScriptsObserver) it.next()).scriptsRemoved(removed); 336 337 } 338 339 } 340 | Popular Tags |