1 19 20 package org.openide.loaders; 21 22 23 import java.beans.*; 24 import java.util.*; 25 import java.util.logging.Level ; 26 import java.util.logging.Logger ; 27 import javax.swing.event.*; 28 import org.openide.filesystems.FileObject; 29 import org.openide.nodes.*; 30 import org.openide.util.RequestProcessor; 31 32 37 final class FolderChildren extends Children.Keys<FolderChildren.Pair> 38 implements PropertyChangeListener, ChangeListener { 39 40 private DataFolder folder; 41 42 private final DataFilter filter; 43 44 private PropertyChangeListener listener; 45 46 private Logger err; 47 48 private boolean refresh; 49 50 private RequestProcessor.Task refreshTask; 51 52 private ChildrenRefreshRunnable refreshRunnable; 53 54 55 private static RequestProcessor refRP = 56 new RequestProcessor("FolderChildren_Refresh"); 58 62 public FolderChildren (DataFolder f) { 63 this (f, DataFilter.ALL); 64 } 65 66 70 public FolderChildren(DataFolder f, DataFilter filter) { 71 this.folder = f; 72 this.filter = filter; 73 this.refreshRunnable = new ChildrenRefreshRunnable(); 74 this.refreshTask = refRP.create(refreshRunnable); 75 this.listener = org.openide.util.WeakListeners.propertyChange(this, folder); 76 err = Logger.getLogger("org.openide.loaders.FolderChildren." + f.getPrimaryFile().getPath().replace('/','.')); } 78 79 80 DataFilter getFilter () { 81 return filter; 82 } 83 84 86 public void propertyChange (final PropertyChangeEvent ev) { 87 if (DataFolder.PROP_CHILDREN.equals (ev.getPropertyName ())) { 88 err.fine("Got PROP_CHILDREN"); 89 refreshChildren().schedule (0); 90 postClearTask(); 91 return; 92 } 93 if ( 94 DataFolder.PROP_SORT_MODE.equals (ev.getPropertyName ()) || 95 DataFolder.PROP_ORDER.equals (ev.getPropertyName ()) 96 ) { 97 err.fine("Got PROP_SORT_MODE or PROP_ORDER"); 98 refreshChildren().schedule (0); 99 postClearTask(); 100 return; 101 } 102 } 103 104 public void stateChanged( ChangeEvent e ) { 105 refresh = true; 107 refreshChildren().schedule(0); 108 postClearTask(); 109 return; 110 } 111 112 117 private void postClearTask() { 118 refRP.post(new Runnable () { 119 public void run() { 120 refreshRunnable.clear(); 121 } 122 }); 123 } 124 125 127 RequestProcessor.Task refreshChildren() { 128 return refreshTask; 129 } 130 131 134 protected Node[] createNodes(Pair key) { 135 err.fine("createNodes: " + key); 136 FileObject fo = key.primaryFile; 137 DataObject obj; 138 try { 139 obj = DataObject.find (fo); 140 if (filter == null || filter.acceptDataObject (obj)) { 141 return new Node[] { obj.getClonedNodeDelegate (filter) }; 142 } else { 143 return new Node[0]; 144 } 145 } catch (DataObjectNotFoundException e) { 146 Logger.getLogger(FolderChildren.class.getName()).log(Level.FINE, null, e); 147 return new Node[0]; 148 } 149 } 150 151 public Node[] getNodes(boolean optimalResult) { 152 Node[] res; 153 Object hold; 154 155 if (optimalResult) { 156 if (checkChildrenMutex()) { 157 err.fine("getNodes(true)"); FolderList.find(folder.getPrimaryFile(), true).waitProcessingFinished(); 159 err.fine("getNodes(true): waitProcessingFinished"); RequestProcessor.Task task = refreshChildren(); 161 res = getNodes(); 162 err.fine("getNodes(true): getNodes: " + res.length); task.schedule(0); 164 task.waitFinished(); 165 err.fine("getNodes(true): waitFinished"); } else { 167 Logger.getLogger(FolderChildren.class.getName()).log(Level.WARNING, null, 168 new java.lang.IllegalStateException ("getNodes(true) called while holding the Children.MUTEX")); 169 } 170 } 171 res = getNodes(); 172 err.fine("getNodes(boolean): post clear task"); postClearTask(); return res; 176 } 177 178 public Node findChild(String name) { 179 if (checkChildrenMutex()) { 180 getNodes(true); 181 } 182 return super.findChild(name); 183 } 184 185 186 187 191 static boolean checkChildrenMutex() { 192 return !Children.MUTEX.isReadAccess() && !Children.MUTEX.isWriteAccess (); 193 } 194 195 197 protected void addNotify () { 198 err.fine("addNotify begin"); 199 folder.addPropertyChangeListener (listener); 201 if ( filter instanceof ChangeableDataFilter ) { 203 ((ChangeableDataFilter)filter).addChangeListener( this ); 204 } 205 refreshChildren().schedule(0); 207 err.fine("addNotify end"); 208 } 209 210 212 protected void removeNotify () { 213 err.fine("removeNotify begin"); 214 folder.removePropertyChangeListener (listener); 216 if ( filter instanceof ChangeableDataFilter ) { 218 ((ChangeableDataFilter)filter).removeChangeListener( this ); 219 } 220 221 setKeys(Collections.<Pair>emptySet()); 223 err.fine("removeNotify end"); 224 } 225 226 227 public String toString () { 228 return (folder != null) ? folder.getPrimaryFile ().toString () : super.toString(); 229 } 230 231 236 private final class ChildrenRefreshRunnable implements Runnable { 237 240 private DataObject[] ch; 241 242 245 public void run() { 246 assert refRP.isRequestProcessorThread(); 248 249 FolderList.find(folder.getPrimaryFile(), true).waitProcessingFinished(); 250 251 ch = folder.getChildren(); 252 err.fine("Children computed"); 253 Pair[] keys = new Pair[ch.length]; 254 for (int i = 0; i < keys.length; i++) { 255 keys[i] = new Pair(ch[i].getPrimaryFile()); 256 } 257 setKeys(Arrays.asList(keys)); 258 259 if ( refresh ) { 260 refresh = false; 261 for (Pair key : keys) { 262 refreshKey(key); 263 } 264 } 265 266 if (!isInitialized()) { 267 clear(); 268 } 269 } 270 271 274 public void clear() { 275 assert refRP.isRequestProcessorThread(); 277 err.fine("Clearing the reference to children"); ch = null; 279 } 280 } 281 282 288 static final class Pair extends Object { 289 public FileObject primaryFile; 290 public int seq; 291 292 public Pair (FileObject primaryFile) { 293 this.primaryFile = primaryFile; 294 this.seq = DataObjectPool.getPOOL().registrationCount(primaryFile); 295 } 296 297 public int hashCode () { 298 return primaryFile.hashCode () ^ seq; 299 } 300 301 public boolean equals (Object o) { 302 if (o instanceof Pair) { 303 Pair p = (Pair)o; 304 return primaryFile.equals (p.primaryFile) && seq == p.seq; 305 } 306 return false; 307 } 308 309 public String toString() { 310 return "FolderChildren.Pair[" + primaryFile + "," + seq + "]"; } 312 } 313 } 314 | Popular Tags |