1 19 20 package org.netbeans.modules.ruby.modules.project.rake; 21 22 import java.io.File ; 23 import java.util.Map ; 24 import java.util.WeakHashMap ; 25 import org.openide.filesystems.FileObject; 26 import java.lang.ref.Reference ; 27 import java.lang.ref.WeakReference ; 28 import java.util.HashMap ; 29 30 import org.openide.filesystems.FileChangeListener; 31 import org.openide.filesystems.FileAttributeEvent; 32 import org.openide.filesystems.FileEvent; 33 import org.openide.filesystems.FileRenameEvent; 34 import org.openide.filesystems.FileUtil; 35 import org.openide.util.Utilities; 36 37 39 48 public final class FileChangeSupport { 49 50 public static FileChangeSupport DEFAULT = new FileChangeSupport(); 51 52 private FileChangeSupport() {} 53 54 private final Map <FileChangeSupportListener,Map <File ,Holder>> holders = new WeakHashMap <FileChangeSupportListener,Map <File ,Holder>>(); 55 56 63 public void addListener(FileChangeSupportListener listener, File path) { 64 assert path.equals(FileUtil.normalizeFile(path)) : "Need to normalize " + path + " before passing to FCS!"; 65 Map <File ,Holder> f2H = holders.get(listener); 66 if (f2H == null) { 67 f2H = new HashMap <File ,Holder>(); 68 holders.put(listener, f2H); 69 } 70 if (f2H.containsKey(path)) { 71 throw new IllegalArgumentException ("Already listening to " + path); } 73 f2H.put(path, new Holder(listener, path)); 74 } 75 76 79 public void removeListener(FileChangeSupportListener listener, File path) { 80 assert path.equals(FileUtil.normalizeFile(path)) : "Need to normalize " + path + " before passing to FCS!"; 81 Map <File ,Holder> f2H = holders.get(listener); 82 if (f2H == null) { 83 throw new IllegalArgumentException ("Was not listening to " + path); } 85 if (!f2H.containsKey(path)) { 86 throw new IllegalArgumentException ("Was not listening to " + path); } 88 f2H.remove(path); 89 } 90 91 private static final class Holder extends WeakReference <FileChangeSupportListener> implements FileChangeListener, Runnable { 92 93 private final File path; 94 private FileObject current; 95 private File currentF; 96 97 public Holder(FileChangeSupportListener listener, File path) { 98 super(listener, Utilities.activeReferenceQueue()); 99 assert path != null; 100 this.path = path; 101 locateCurrent(); 102 } 103 104 private void locateCurrent() { 105 FileObject oldCurrent = current; 106 currentF = path; 107 while (true) { 108 try { 109 current = FileUtil.toFileObject(currentF); 110 } catch (IllegalArgumentException x) { 111 currentF = FileUtil.normalizeFile(currentF); 113 current = FileUtil.toFileObject(currentF); 114 } 115 if (current != null) { 116 break; 117 } 118 currentF = currentF.getParentFile(); 119 if (currentF == null) { 120 return; 123 } 124 } 125 assert current != null; 127 if (current != oldCurrent) { 128 if (oldCurrent != null) { 129 oldCurrent.removeFileChangeListener(this); 130 } 131 current.addFileChangeListener(this); 132 current.getChildren(); } 134 } 135 136 private void someChange(FileObject modified) { 137 FileChangeSupportListener listener; 138 FileObject oldCurrent, nueCurrent; 139 File oldCurrentF, nueCurrentF; 140 synchronized (this) { 141 if (current == null) { 142 return; 143 } 144 listener = get(); 145 if (listener == null) { 146 return; 147 } 148 oldCurrent = current; 149 oldCurrentF = currentF; 150 locateCurrent(); 151 nueCurrent = current; 152 nueCurrentF = currentF; 153 } 154 if (modified != null && modified == nueCurrent) { 155 FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_MODIFIED, path); 156 listener.fileModified(event); 157 } else { 158 boolean oldWasCorrect = path.equals(oldCurrentF); 159 boolean nueIsCorrect = path.equals(nueCurrentF); 160 if (oldWasCorrect && !nueIsCorrect) { 161 FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_DELETED, path); 162 listener.fileDeleted(event); 163 } else if (nueIsCorrect && !oldWasCorrect) { 164 FileChangeSupportEvent event = new FileChangeSupportEvent(DEFAULT, FileChangeSupportEvent.EVENT_CREATED, path); 165 listener.fileCreated(event); 166 } 167 } 168 } 169 170 public void fileChanged(FileEvent fe) { 171 someChange(fe.getFile()); 172 } 173 174 public void fileDeleted(FileEvent fe) { 175 someChange(null); 176 } 177 178 public void fileDataCreated(FileEvent fe) { 179 someChange(null); 180 } 181 182 public void fileFolderCreated(FileEvent fe) { 183 someChange(null); 184 } 185 186 public void fileRenamed(FileRenameEvent fe) { 187 someChange(null); 188 } 189 190 public void fileAttributeChanged(FileAttributeEvent fe) { 191 } 193 194 public synchronized void run() { 195 if (current != null) { 196 current.removeFileChangeListener(this); 197 current = null; 198 } 199 } 200 201 } 202 203 } 204 | Popular Tags |