package runjettyrun.scanner; import java.io.File; import java.util.HashSet; import java.util.List; import java.util.Set; import org.mortbay.jetty.webapp.WebAppContext; import org.mortbay.util.Scanner; import runjettyrun.Configs; import runjettyrun.ProjectClassLoader; /** * For more details controll we need, * ex. when add a folder , it's unncessory to restart. * @author tony * */ public class RJRFileChangeListener implements Scanner.BulkListener,Scanner.DiscreteListener { /** * Logger for this class */ private WebAppContext web; private Configs config; private boolean init = false; private Set<String> folderSet; private boolean isDirty = false; private Set<String> dirtylist = new HashSet<String>(); public RJRFileChangeListener(WebAppContext web, Configs config) { super(); folderSet= new HashSet<String>(); this.web = web; this.config = config; } public void fileChanged(String filename) throws Exception { if(!init){ //do nothing when init. return ; } //2011/12/19 TonyQ:If the sub files or folders is added or removed , the parent folder will //be notified as changed , so we have to ignore parent folder! // // if (logger.isDebugEnabled()) { // File f = new File(filename); // logger.debug("fileChanged(String) - changed:" + filename + ":" // + f.exists() + ":" + f.isDirectory()); // } if(isIgnored(filename)){ return; } boolean isFolder = (folderSet.contains(filename)); isDirty = isDirty || !isFolder; // if user change a file, we should restart the server, but not for folder. if(!isFolder){ dirtylist.add("*"+filename); } } public void fileAdded(String filename) throws Exception { File f = new File(filename); if(f.isDirectory()){ folderSet.add(filename); // if(!init ){ // if (logger.isDebugEnabled()) { // logger.debug("fileAdded(String) - init add folder:" // + filename); // } // }else{ // if (logger.isDebugEnabled()) { // logger.debug("fileAdded(String) - add folder:" + filename); // } // } } if(!init){ return ; } // if (logger.isDebugEnabled()) { // logger.debug("fileAdded(String) - added:" + filename); // } if(isIgnored(filename)){ return; } if(f.isFile()){ dirtylist.add("+"+filename); } isDirty = isDirty || f.isFile(); //if user adding a file , we should restart the server, but not for folders. } private boolean isIgnored(String filename){ return (config.getIgnoreScanClassFile() && filename.endsWith(".class") && !folderSet.contains(filename)); } public void fileRemoved(String filename) throws Exception { if(!init){ //do nothing when init. return ; } // if (logger.isDebugEnabled()) { // logger.debug("fileRemoved(String) - removed:" + filename); // } if(isIgnored(filename)){ return; } boolean isFolder = folderSet.contains(filename); if(isFolder){ folderSet.remove(filename); }else{ dirtylist.add("-"+filename); } isDirty = isDirty || !isFolder; // if user adding a file , we should restart the server , but not for folders. } /** * @param filenames it's actually a string list. * @throws Exception */ public void filesChanged(@SuppressWarnings("rawtypes") List changes) throws Exception { if(!init){ init = true; //ignore first time return ; } try { if(!isDirty) return ; System.err.println("Stopping webapp ..."); System.err.println("File changed:"); for(String str:dirtylist){ System.err.println(str); } web.stop(); if (config.getWebAppClassPath() != null) { ProjectClassLoader loader = new ProjectClassLoader(web, config.getWebAppClassPath(), config.getExcludedclasspath(), false); web.setClassLoader(loader); } System.err.println("Restarting webapp ..."); web.start(); System.err.println("Restart completed."); } catch (Exception e) { System.err.println( "Error reconfiguring/restarting webapp after change in watched files"); e.printStackTrace(); }finally{ isDirty = false; dirtylist.clear(); } } }