diff -r 612e5ffe9ad3 favorites/src/org/netbeans/modules/favorites/Favorites.java --- a/favorites/src/org/netbeans/modules/favorites/Favorites.java Mon Oct 20 18:14:10 2008 +0200 +++ b/favorites/src/org/netbeans/modules/favorites/Favorites.java Mon Oct 20 18:32:15 2008 +0200 @@ -61,16 +61,18 @@ import org.openide.filesystems.FileStateInvalidException; import org.openide.filesystems.FileUtil; import org.openide.filesystems.Repository; +import org.openide.loaders.ChangeableDataFilter; +import org.openide.loaders.DataFilter; import org.openide.loaders.DataFolder; import org.openide.loaders.DataObject; import org.openide.loaders.DataShadow; import org.openide.nodes.FilterNode; import org.openide.nodes.Index; import org.openide.nodes.Node; +import org.openide.util.ChangeSupport; import org.openide.util.Exceptions; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; -import org.openide.util.Utilities; import org.openide.util.datatransfer.PasteType; /** @@ -287,43 +289,71 @@ } } - private static class Chldrn extends FilterNode.Children - implements ChangeListener, Runnable { + + + static class VisQ + implements DataFilter.Lowlevel, ChangeableDataFilter, ChangeListener { + public static final VisQ DEFAULT = new VisQ(); + private ChangeListener weak; - private boolean hideHidden; - /** Creates new Chldrn. */ - public Chldrn (Node node, boolean hideHidden) { - super (node); - this.hideHidden = hideHidden; - + private ChangeSupport support = new ChangeSupport(this); + + VisQ() { weak = org.openide.util.WeakListeners.change(this, VisibilityQuery.getDefault()); VisibilityQuery.getDefault().addChangeListener(weak); } + public boolean acceptFileObject(FileObject fo) { + return VisibilityQuery.getDefault().isVisible(fo); + } + + public boolean acceptDataObject(DataObject obj) { + return VisibilityQuery.getDefault().isVisible(obj.getPrimaryFile()); + } + + public void addChangeListener(ChangeListener listener) { + support.addChangeListener(listener); + } + + public void removeChangeListener(ChangeListener listener) { + support.removeChangeListener(listener); + } + + public void stateChanged(ChangeEvent e) { + support.fireChange(); + } + } // end of VisQ + + private static class Chldrn extends FilterNode.Children { + private boolean hideHidden; + /** Creates new Chldrn. */ + public Chldrn(Node node, boolean hideHidden) { + super (node); + this.hideHidden = hideHidden; + } + @Override protected Node[] createNodes(Node node) { + org.openide.nodes.Children ch = Children.LEAF; + DataObject obj = node.getLookup().lookup(DataObject.class); if (hideHidden) { - DataObject obj = node.getCookie(DataObject.class); if (obj != null && !VisibilityQuery.getDefault().isVisible(obj.getPrimaryFile())) { return null; } } + + DataFolder folder = node.getLookup().lookup(DataFolder.class); + if (folder != null) { + ch = new Chldrn(new FilterNode(node, folder.createNodeChildren(new VisQ())), true); + } else { + if (node.isLeaf()) { + ch = org.openide.nodes.Children.LEAF; + } else { + ch = new Chldrn(node, true); + } + } - return new Node[] { new ProjectFilterNode ( - node, - (node.isLeaf ()) ? org.openide.nodes.Children.LEAF : new Chldrn (node, true) - )}; - } - - public void stateChanged(ChangeEvent e) { - MUTEX.postWriteRequest(this); - } - - public void run() { - Node[] arr = original.getChildren().getNodes(); - for (int i = 0; i < arr.length; i++) { - refreshKey(arr[i]); - } + return new Node[] { new ProjectFilterNode (node, ch) }; } } // end of Chldrn diff -r 612e5ffe9ad3 favorites/test/unit/src/org/netbeans/modules/favorites/VisibilityQueryWorksTest.java --- a/favorites/test/unit/src/org/netbeans/modules/favorites/VisibilityQueryWorksTest.java Mon Oct 20 18:14:10 2008 +0200 +++ b/favorites/test/unit/src/org/netbeans/modules/favorites/VisibilityQueryWorksTest.java Mon Oct 20 18:32:15 2008 +0200 @@ -85,6 +85,7 @@ /** If execution fails we wrap the exception with * new log message. */ + @Override protected void runTest () throws Throwable { try { super.runTest (); @@ -96,6 +97,7 @@ } + @Override protected void setUp () throws Exception { clearWorkDir(); @@ -193,7 +195,10 @@ VQI vqi = (VQI) Lookup.getDefault().lookup(VQI.class); vqi.showAll = true; vqi.fire(); - + + // initialize the children + Node some = f.getChildren().findChild(null); + assertNotNull("Some node needs to be found", some); arr = f.getChildren().getNodes(true); assertNodeForDataObject("hidden object is now there", hiddenDO, true, arr); assertEquals("One child at all", 1, arr.length); diff -r 612e5ffe9ad3 openide.loaders/manifest.mf --- a/openide.loaders/manifest.mf Mon Oct 20 18:14:10 2008 +0200 +++ b/openide.loaders/manifest.mf Mon Oct 20 18:32:15 2008 +0200 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.loaders -OpenIDE-Module-Specification-Version: 7.2 +OpenIDE-Module-Specification-Version: 7.3 OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties OpenIDE-Module-Recommends: org.netbeans.modules.templates.v1_0 AutoUpdate-Essential-Module: true diff -r 612e5ffe9ad3 openide.loaders/src/org/openide/loaders/DataFilter.java --- a/openide.loaders/src/org/openide/loaders/DataFilter.java Mon Oct 20 18:14:10 2008 +0200 +++ b/openide.loaders/src/org/openide/loaders/DataFilter.java Mon Oct 20 18:32:15 2008 +0200 @@ -41,6 +41,8 @@ package org.openide.loaders; +import org.openide.filesystems.FileObject; + /** Allows certain data objects to be excluded from being displayed. * @see RepositoryNodeFactory @@ -61,4 +63,17 @@ /** @deprecated Only public by accident. */ @Deprecated /* public static final */ long serialVersionUID = 0L; + + /** Additional interface that can be implemented by the {@link DataFilter} + * implementors to do low level filtering based on the file objects. + */ + public interface Lowlevel extends DataFilter { + /** Should this fileobject be considered for displaying? + * + * @param fo the file object + * @return true if the object should be displayed, + * false otherwise + */ + public boolean acceptFileObject(FileObject fo); + } } diff -r 612e5ffe9ad3 openide.loaders/src/org/openide/loaders/FolderChildren.java --- a/openide.loaders/src/org/openide/loaders/FolderChildren.java Mon Oct 20 18:14:10 2008 +0200 +++ b/openide.loaders/src/org/openide/loaders/FolderChildren.java Mon Oct 20 18:32:15 2008 +0200 @@ -152,6 +152,12 @@ Arrays.sort(arr, order); List positioned = new ArrayList(arr.length); for (FileObject fo : FileUtil.getOrder(Arrays.asList(arr), false)) { + if (filter instanceof DataFilter.Lowlevel) { + DataFilter.Lowlevel f =(DataFilter.Lowlevel)filter; + if (!f.acceptFileObject(fo)) { + continue; + } + } positioned.add(new FolderChildrenPair(fo)); } diff -r 612e5ffe9ad3 openide.loaders/test/unit/src/org/openide/loaders/FolderChildrenTest.java --- a/openide.loaders/test/unit/src/org/openide/loaders/FolderChildrenTest.java Mon Oct 20 18:14:10 2008 +0200 +++ b/openide.loaders/test/unit/src/org/openide/loaders/FolderChildrenTest.java Mon Oct 20 18:32:15 2008 +0200 @@ -47,6 +47,7 @@ import java.io.IOException; import java.util.*; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.event.ChangeEvent; @@ -58,12 +59,15 @@ import org.netbeans.junit.NbTestCase; import org.netbeans.junit.NbTestSuite; import org.netbeans.junit.RandomlyFails; +import org.netbeans.spi.queries.VisibilityQueryImplementation; import org.openide.filesystems.*; import org.openide.loaders.DefaultDataObjectTest.JspLoader; import org.openide.loaders.MultiDataObject.Entry; +import org.openide.nodes.AbstractNode; import org.openide.nodes.Node; import org.openide.nodes.Children; +import org.openide.nodes.FilterNode; import org.openide.nodes.NodeEvent; import org.openide.nodes.NodeListener; import org.openide.nodes.NodeMemberEvent; @@ -95,7 +99,7 @@ public static Test suite() { Test t = null; -// t = new FolderChildrenTest("testDeadlockWithChildrenMutex"); +// t = new FolderChildrenTest("testALotOfHiddenEntries"); if (t == null) { t = new NbTestSuite(FolderChildrenTest.class); } @@ -732,6 +736,84 @@ assertNodes( arr, new String[] { "A" } ); } + public void testALotOfHiddenEntries() throws Exception { + FileSystem fs = Repository.getDefault ().getDefaultFileSystem(); + FileObject folder = FileUtil.createFolder(fs.getRoot(), "aLotOf"); + List arr = new ArrayList(); + final int FILES = 1000; + for (int i = 0; i < FILES; i++) { + arr.add(FileUtil.createData(folder, "" + i + ".dat")); + } + + DataFolder df = DataFolder.findFolder(folder); + + VisQ visq = new VisQ(); + + FilterNode fn = new FilterNode(new FilterNode(new AbstractNode(df.createNodeChildren(visq)))); + class L implements NodeListener { + int cnt; + + public void childrenAdded(NodeMemberEvent ev) { + cnt++; + } + + public void childrenRemoved(NodeMemberEvent ev) { + cnt++; + } + + public void childrenReordered(NodeReorderEvent ev) { + cnt++; + } + + public void nodeDestroyed(NodeEvent ev) { + cnt++; + } + + public void propertyChange(PropertyChangeEvent evt) { + cnt++; + } + } + L listener = new L(); + fn.addNodeListener(listener); + + List nodes = new ArrayList(); + int cnt = fn.getChildren().getNodesCount(true); + List snapshot = fn.getChildren().snapshot(); + assertEquals("Count as expected", cnt, snapshot.size()); + for (int i = 0; i < cnt; i++) { + nodes.add(snapshot.get(i)); + } + assertEquals("No events delivered", 0, listener.cnt); + assertEquals("Size is half cut", FILES / 2, fn.getChildren().getNodesCount(true)); + } + + public static final class VisQ implements VisibilityQueryImplementation, DataFilter.Lowlevel { + public boolean isVisible(FileObject file) { + try { + int number = Integer.parseInt(file.getName()); + return number % 2 == 0; + } catch (NumberFormatException numberFormatException) { + return true; + } + } + + public void addChangeListener(ChangeListener l) { + } + + public void removeChangeListener(ChangeListener l) { + } + + public boolean acceptDataObject(DataObject obj) { + return isVisible(obj.getPrimaryFile()); + } + + public boolean acceptFileObject(FileObject obj) { + return isVisible(obj); + } + + } + + public static final class Pool extends DataLoaderPool { private static Class loader;