diff -r e2f49f33340d masterfs/apichanges.xml --- a/masterfs/apichanges.xml Wed Apr 07 10:36:38 2010 +0200 +++ b/masterfs/apichanges.xml Wed Apr 07 14:44:34 2010 +0200 @@ -46,6 +46,23 @@ MasterFileSystem API + + + ProvidedExtensions.refreshRecursively was added. + + + + + +

+ ProvidedExtensions.refreshRecursively allows + various version control providers to get better control + on behavior of recursive listener. +

+
+ + +
ProvidedExtensions.canWrite was added. diff -r e2f49f33340d masterfs/manifest.mf --- a/masterfs/manifest.mf Wed Apr 07 10:36:38 2010 +0200 +++ b/masterfs/manifest.mf Wed Apr 07 14:44:34 2010 +0200 @@ -1,7 +1,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.masterfs/2 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/masterfs/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 2.22 +OpenIDE-Module-Specification-Version: 2.23 AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true diff -r e2f49f33340d masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectKeeper.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectKeeper.java Wed Apr 07 10:36:38 2010 +0200 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectKeeper.java Wed Apr 07 14:44:34 2010 +0200 @@ -41,8 +41,9 @@ import java.io.File; import java.util.Collection; -import java.util.Enumeration; import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.CopyOnWriteArraySet; @@ -61,7 +62,7 @@ final class FileObjectKeeper implements FileChangeListener { private static final Logger LOG = Logger.getLogger(FileObjectKeeper.class.getName()); - private Set kept; + private Set kept; private Collection listeners; private final FolderObj root; private long timeStamp; @@ -94,47 +95,47 @@ } } - public void init(long previous, FileObjectFactory factory, boolean expected) { + public List init(long previous, FileObjectFactory factory, boolean expected) { File file = root.getFileName().getFile(); - File[] arr = file.listFiles(); - long ts = 0; - if (arr != null) { - for (File f : arr) { - if (f.isDirectory()) { - continue; - } - long lm = f.lastModified(); - LOG.log(Level.FINE, " check {0} for {1}", new Object[] { lm, f }); - if (lm > ts) { - ts = lm; - } - if (lm > previous && factory != null) { - final BaseFileObj prevFO = factory.getCachedOnly(f); - if (prevFO == null) { - BaseFileObj who = factory.getValidFileObject(f, Caller.Others); - if (who != null) { - LOG.log(Level.FINE, "External change detected {0}", who); //NOI18N - who.fireFileChangedEvent(expected); - } else { - LOG.log(Level.FINE, "Cannot get valid FileObject. File probably removed: {0}", f); //NOI18N - } + LinkedList arr = new LinkedList(); + long ts = root.getProvidedExtensions().refreshRecursively(file, previous, arr); + for (File f : arr) { + if (f.isDirectory()) { + continue; + } + long lm = f.lastModified(); + LOG.log(Level.FINE, " check {0} for {1}", new Object[] { lm, f }); + if (lm > ts) { + ts = lm; + } + if (lm > previous && factory != null) { + final BaseFileObj prevFO = factory.getCachedOnly(f); + if (prevFO == null) { + BaseFileObj who = factory.getValidFileObject(f, Caller.Others); + if (who != null) { + LOG.log(Level.FINE, "External change detected {0}", who); //NOI18N + who.fireFileChangedEvent(expected); } else { - LOG.log(Level.FINE, "Do classical refresh for {0}", prevFO); //NOI18N - prevFO.refresh(expected, true); + LOG.log(Level.FINE, "Cannot get valid FileObject. File probably removed: {0}", f); //NOI18N } + } else { + LOG.log(Level.FINE, "Do classical refresh for {0}", prevFO); //NOI18N + prevFO.refresh(expected, true); } } } timeStamp = ts; LOG.log(Level.FINE, "Testing {0}, time {1}", new Object[] { file, timeStamp }); + return arr; } - private void listenTo(FileObject fo, boolean add) { + private void listenTo(FolderObj fo, boolean add, Collection children) { if (add) { fo.addFileChangeListener(this); if (fo instanceof FolderObj) { FolderObj folder = (FolderObj)fo; - folder.getKeeper(); + folder.getKeeper(children); + folder.getChildren(); kept.add(folder); } LOG.log(Level.FINER, "Listening to {0}", fo); @@ -147,11 +148,19 @@ private void listenToAll(Callable stop) { assert Thread.holdsLock(this); assert kept == null; - kept = new HashSet(); - listenTo(root, true); - Enumeration en = root.getChildren(true); - while (en.hasMoreElements()) { - FileObject fo = en.nextElement(); + kept = new HashSet(); + LinkedList it = new LinkedList(); + listenTo(root, true, it); + FileObjectFactory factory = null; + for (;;) { + File f = it.poll(); + if (f == null) { + break; + } + if (factory == null) { + factory = FileObjectFactory.getInstance(f); + } + FileObject fo = factory.getValidFileObject(f, Caller.Others); if (fo instanceof FolderObj) { FolderObj obj = (FolderObj) fo; Object shallStop = null; @@ -166,7 +175,7 @@ LOG.log(Level.INFO, "addRecursiveListener to {0} interrupted", root); // NOI18N return; } - listenTo(obj, true); + listenTo(obj, true, it); } } } @@ -174,11 +183,11 @@ private void listenNoMore() { assert Thread.holdsLock(this); - listenTo(root, false); - Set k = kept; + listenTo(root, false, null); + Set k = kept; if (k != null) { - for (FileObject fo : k) { - listenTo(fo, false); + for (FolderObj fo : k) { + listenTo(fo, false, null); } kept = null; } @@ -187,15 +196,24 @@ @Override public void fileFolderCreated(FileEvent fe) { Collection arr = listeners; - final FileObject f = fe.getFile(); - if (f instanceof FolderObj) { + final FileObject folder = fe.getFile(); + if (folder instanceof FolderObj) { + FolderObj obj = (FolderObj)folder; synchronized (this) { - listenTo(f, true); - Enumeration en = f.getChildren(true); - while (en.hasMoreElements()) { - FileObject fo = en.nextElement(); + LinkedList it = new LinkedList(); + listenTo(obj, true, it); + FileObjectFactory factory = null; + for (;;) { + File f = it.poll(); + if (f == null) { + break; + } + if (factory == null) { + factory = FileObjectFactory.getInstance(f); + } + FileObject fo = factory.getValidFileObject(f, Caller.Others); if (fo instanceof FolderObj) { - listenTo(fo, true); + listenTo((FolderObj)fo, true, it); } } } @@ -240,11 +258,12 @@ } if (f instanceof FolderObj) { + FolderObj obj = (FolderObj)f; synchronized (this) { if (kept != null) { - kept.remove(f); + kept.remove(obj); } - listenTo(f, false); + listenTo(obj, false, null); } } if (arr == null) { diff -r e2f49f33340d masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObj.java --- a/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObj.java Wed Apr 07 10:36:38 2010 +0200 +++ b/masterfs/src/org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObj.java Wed Apr 07 14:44:34 2010 +0200 @@ -48,6 +48,7 @@ import java.io.OutputStream; import java.io.SyncFailedException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -70,7 +71,6 @@ import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; -import org.openide.util.Exceptions; import org.openide.util.Mutex; /** @@ -520,22 +520,28 @@ return folderChildren; } - synchronized FileObjectKeeper getKeeper() { + synchronized FileObjectKeeper getKeeper(Collection arr) { if (keeper == null) { keeper = new FileObjectKeeper(this); - keeper.init(-1, null, false); + List ch = keeper.init(-1, null, false); + if (arr != null) { + arr.addAll(ch); + } + } else if (arr != null) { + List ch = keeper.init(keeper.childrenLastModified(), null, false); + arr.addAll(ch); } return keeper; } @Override public final void addRecursiveListener(FileChangeListener fcl) { - getKeeper().addRecursiveListener(fcl); + getKeeper(null).addRecursiveListener(fcl); } @Override public final void removeRecursiveListener(FileChangeListener fcl) { - getKeeper().removeRecursiveListener(fcl); + getKeeper(null).removeRecursiveListener(fcl); } diff -r e2f49f33340d masterfs/src/org/netbeans/modules/masterfs/providers/ProvidedExtensions.java --- a/masterfs/src/org/netbeans/modules/masterfs/providers/ProvidedExtensions.java Wed Apr 07 10:36:38 2010 +0200 +++ b/masterfs/src/org/netbeans/modules/masterfs/providers/ProvidedExtensions.java Wed Apr 07 14:44:34 2010 +0200 @@ -43,6 +43,8 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.List; import org.openide.filesystems.FileObject; /** @@ -187,4 +189,26 @@ public Object getAttribute(File file, String attrName) { return null; } + + /** Allows versioning system to exclude some children from recursive + * listening check. Also notifies the versioning whenever a refresh + * is required and allows the versiniong to provide special timestamp + * for a directory. + * + * @param dir the directory to check timestamp for + * @param lastTimeStamp the previously known timestamp or -1 + * @param children add children that shall be interated into this array + * @return the timestamp that shall represent this directory, it will + * be compared with timestamps of all children and the newest + * one will be kept and next time passed as lastTimeStamp. Return + * 0 if the directory does not have any special timestamp + * @since 2.23 + */ + public long refreshRecursively(File dir, long lastTimeStamp, List children) { + final File[] arr = dir.listFiles(); + if (arr != null) { + children.addAll(Arrays.asList(arr)); + } + return 0; + } }