1 19 20 21 package org.netbeans.modules.masterfs; 22 23 import java.io.*; 24 import org.netbeans.modules.masterfs.providers.*; 25 import org.netbeans.modules.masterfs.providers.AnnotationProvider; 26 import org.openide.filesystems.*; 27 import org.openide.util.NbBundle; 28 import org.openide.util.actions.SystemAction; 29 import org.openide.util.Utilities; 30 31 import java.awt.*; 32 import java.beans.PropertyVetoException ; 33 import java.io.File ; 34 import java.io.Serializable ; 35 import java.util.*; 36 import org.openide.util.Exceptions; 37 38 44 final public class MasterFileSystem extends FileSystem implements FileStatusListener { 45 46 private static final long serialVersionUID = -97134851800761145L; 47 transient private static MasterFileSystem instance; 49 transient private final StatusImpl status = new StatusImpl(); 50 51 static MasterFileSystem getDefault() { 52 boolean init = false; 53 synchronized (MasterFileSystem.class) { 54 if (instance == null) { 55 instance = new MasterFileSystem(); 56 init = true; 57 } 58 59 } 60 if (init) { 61 ProviderCall.init(); 62 } 63 return instance; 64 } 65 66 public static MasterFileSystem settingsFactory(FileObject inst) { 67 return getDefault(); 68 } 69 70 private MasterFileSystem() { 71 init(); 72 } 73 74 private Object writeReplace () { 75 return new Replace (); 76 } 77 78 private void init() { 79 try { 80 setSystemName(getClass().getName()); } catch (PropertyVetoException pvx) { 82 } 85 registerFileStatusListener(); 86 } 87 88 private void registerFileStatusListener() { 89 Enumeration en = MountTable.getDefault().geAllFileSystems(); 90 while (en.hasMoreElements()) { 91 FileSystem fs = (FileSystem) en.nextElement(); 92 fs.addNotify(); 93 fs.addFileStatusListener(this); 94 } 95 } 96 97 public String getDisplayName() { 98 return NbBundle.getMessage(MasterFileSystem.class, "LBL_this_computer"); 99 } 100 101 public boolean isReadOnly() { 103 return false; 104 } 105 106 public FileObject getRoot() { 107 return Cache.getDefault().getOrCreate(ResourcePath.getRoot()); 108 } 109 110 public FileObject findResource(String name) { 111 ResourcePath resPath = new ResourcePath (name); 112 FileObject retVal = Cache.getDefault().get(resPath); 113 if (Utilities.getOperatingSystem() == Utilities.OS_VMS) { 114 if (retVal == null) retVal = getStepByStepVMS(resPath); 115 } else { 116 if (retVal == null) retVal = getStepByStep(resPath); 117 } 118 return retVal; 119 } 120 121 125 private FileObject getStepByStep(ResourcePath resPath) { 126 FileObject retVal = getRoot(); 127 Enumeration elems = resPath.getElements(); 128 while (elems.hasMoreElements()) { 129 String nameExt = (String )elems.nextElement(); 130 retVal = retVal.getFileObject(nameExt); 131 if (retVal == null) return null; 132 } 133 return retVal; 134 } 135 136 140 private static String findVMSRoot(String name) { 141 if (name.length() > 0) { 142 StringTokenizer stok = new StringTokenizer(name, "/"); 143 String rootName = ""; 144 while (stok.hasMoreTokens()) { 145 rootName += "/" + stok.nextToken(); 146 if (new File (rootName).exists()) { 147 return rootName; 148 } 149 } 150 } 151 return null; 152 } 153 154 159 private static FileObject getRootForVMS(String name) { 160 return Cache.getDefault().getOrCreate(new ResourcePath(name)); 161 } 162 163 167 private static FileObject getStepByStepVMS(ResourcePath resPath) { 168 String root = findVMSRoot(resPath.getNormalizedPath()); 171 if (root == null) 172 return null; 173 174 FileObject retVal = getRootForVMS(root); 175 ResourcePath subPath = new ResourcePath( 178 resPath.getNormalizedPath().substring(root.length())); 179 Enumeration elems = subPath.getElements(); 180 181 while (elems.hasMoreElements()) { 182 String nameExt = (String )elems.nextElement(); 183 if (nameExt.equals("000000")) 186 continue; 187 retVal = retVal.getFileObject(nameExt); 188 if (retVal == null) return null; 189 } 190 return retVal; 191 } 192 193 194 public void addNotify() { 195 } 196 197 public void removeNotify() { 198 Cache.getDefault().clear(); 199 } 200 201 202 public void refresh(boolean expected) { 203 Enumeration en = MountTable.getDefault().geAllFileSystems(); 204 while (en.hasMoreElements()) { 205 FileSystem fs = (FileSystem) en.nextElement(); 206 fs.refresh(expected); 207 } 208 } 209 210 211 public SystemAction[] getActions() { 212 return getEmptyActions(); 213 } 214 215 private SystemAction[] getEmptyActions() { 216 return new SystemAction[]{}; 217 } 218 219 public SystemAction[] getActions(java.util.Set foSet) { 220 SystemAction[] some = status.getActions (foSet); 221 if (some != null) { 222 return some; 223 } 224 225 SyncSection.getDefault().enterSection(); 226 try { 227 MasterFileObject hfo = getUniqueMasterFileObject(foSet); 229 if (hfo == null) return getEmptyActions(); 230 231 FileSystem firstFs = getDelegateFileSystem(hfo.getDelegate().get()); 232 FileSystem secondFs = getDelegateFileSystem(hfo.getDelegate().getPrefered()); 233 if (firstFs == null) return getEmptyActions(); 234 235 if (secondFs != firstFs ) { 236 return mergeActionsFromBothDelegates(foSet, firstFs, secondFs); 237 } 238 239 return firstFs.getActions(Utils.transformToDelegates(foSet, false)); 240 } finally { 241 SyncSection.getDefault().finishSection(); 242 } 243 } 244 245 private static FileSystem getDelegateFileSystem(FileObject foDel) { 246 if (foDel == null) return null; 247 FileSystem fsDel = null; 248 try { 249 fsDel = foDel.getFileSystem(); 250 } catch (FileStateInvalidException e) { 251 return null; 252 } 253 return fsDel; 254 } 255 256 private static MasterFileObject getUniqueMasterFileObject(Set hfoSet) { 257 MasterFileObject retVal = null; 258 FileSystem lastFs = null; 259 for (Iterator it = hfoSet.iterator(); it.hasNext();) { 260 Object o = it.next(); 261 if (!(o instanceof MasterFileObject)) return null; 262 263 retVal = (MasterFileObject) o; 264 FileObject deleg = retVal.getDelegate().get(); 265 if (deleg == null) continue; 266 FileSystem fs = getDelegateFileSystem(deleg); 267 if (fs == null) continue; 268 269 if (lastFs != null && lastFs != fs) return null; 270 lastFs = fs; 271 } 272 return retVal; 273 } 274 275 private SystemAction[] mergeActionsFromBothDelegates(Set hfoSet, FileSystem firstFs, FileSystem secondFs) { 276 Set mergedActions = new HashSet(hfoSet.size()); 277 278 Set firstSet = Utils.transformToDelegates(hfoSet, false); 279 SystemAction[] firstActions = firstFs.getActions(firstSet); 280 mergedActions.addAll(Arrays.asList(firstActions)); 281 282 Set secondSet = Utils.transformToDelegates(hfoSet, true); 283 SystemAction[] secondActions = secondFs.getActions(secondSet); 284 mergedActions.addAll(Arrays.asList(secondActions)); 285 286 return (SystemAction[]) mergedActions.toArray(new SystemAction[mergedActions.size()]); 287 } 288 289 290 293 public void annotationChanged(final FileStatusEvent ev) { 294 297 HashSet set = new HashSet(1) { 298 public boolean contains(Object o) { 299 if (o instanceof MasterFileObject) { 300 MasterFileObject fo = (MasterFileObject) o; 301 FileObject deleg = fo.getDelegate().get(); 302 return deleg != null && ev.hasChanged(deleg); 303 } 304 return false; 305 } 306 }; 307 308 309 fireFileStatusChanged(new FileStatusEvent( 310 this, set, ev.isIconChange(), ev.isNameChange() 311 )); 312 } 313 314 315 public FileSystem.Status getStatus() { 316 return status; 317 } 318 319 final void fireFileStatus (FileStatusEvent event) { 320 fireFileStatusChanged(event); 321 } 322 323 324 static final class StatusImpl implements FileSystem.HtmlStatus, 325 org.openide.util.LookupListener, org.openide.filesystems.FileStatusListener { 326 327 private org.openide.util.Lookup.Result annotationProviders; 328 private Collection previousProviders; 329 { 330 annotationProviders = org.openide.util.Lookup.getDefault ().lookup ( 331 new org.openide.util.Lookup.Template (AnnotationProvider.class) 332 ); 333 annotationProviders.addLookupListener (this); 334 resultChanged (null); 335 } 336 337 public ProvidedExtensions getExtensions() { 338 Collection c = (previousProviders != null) ? 339 Collections.unmodifiableCollection(previousProviders) : Collections.EMPTY_LIST; 340 return new ProvidedExtensionsProxy(c); 341 } 342 343 public void resultChanged (org.openide.util.LookupEvent ev) { 344 java.util.Collection now = annotationProviders.allInstances (); 345 java.util.Collection add; 346 347 if (previousProviders != null) { 348 add = new HashSet (now); 349 add.removeAll (previousProviders); 350 351 HashSet toRemove = new HashSet(previousProviders); 352 toRemove.removeAll (now); 353 java.util.Iterator it = toRemove.iterator (); 354 while (it.hasNext ()) { 355 AnnotationProvider ap = (AnnotationProvider)it.next (); 356 ap.removeFileStatusListener (this); 357 } 358 359 } else { 360 add = now; 361 } 362 363 364 365 java.util.Iterator it = add.iterator (); 366 while (it.hasNext ()) { 367 AnnotationProvider ap = (AnnotationProvider)it.next (); 368 try { 369 ap.addFileStatusListener (this); 370 } catch (java.util.TooManyListenersException ex) { 371 Exceptions.printStackTrace(ex); 372 } 373 } 374 375 previousProviders = now; 376 } 377 378 public SystemAction[] getActions(java.util.Set foSet) { 379 380 javax.swing.Action [] retVal = null; 381 java.util.Iterator it = annotationProviders.allInstances ().iterator (); 382 while (retVal == null && it.hasNext ()) { 383 AnnotationProvider ap = (AnnotationProvider)it.next (); 384 retVal = ap.actions (foSet); 385 } 386 if (retVal != null) { 387 SystemAction[] ret = new SystemAction[retVal.length]; 389 for (int i = 0; i < retVal.length; i++) { 390 if (retVal[i] instanceof SystemAction) { 391 ret[i] = (SystemAction)retVal[i]; 392 } 393 } 394 return ret; 395 } 396 return null; 397 } 398 399 public void annotationChanged (org.openide.filesystems.FileStatusEvent ev) { 400 if (ev.getSource () != MasterFileSystem.getDefault ()) { 401 throw new IllegalStateException ("The source must be master fs and not : " + ev.getSource ()); } 403 MasterFileSystem.getDefault ().fireFileStatusChanged (ev); 404 } 405 406 private FileSystem getDelegateFileSystem (Set files) { 407 FileSystem retVal = null; 408 Iterator it = files.iterator(); 409 if (it.hasNext()) { 410 MasterFileObject mfo = (MasterFileObject)it.next(); 411 retVal = mfo.getDelegateFileSystem(); 412 413 } 414 return retVal; 415 } 416 417 public Image annotateIcon(Image icon, int iconType, Set files) { 418 Image retVal = null; 419 420 Iterator it = annotationProviders.allInstances ().iterator (); 421 while (retVal == null && it.hasNext ()) { 422 AnnotationProvider ap = (AnnotationProvider)it.next (); 423 retVal = ap.annotateIcon (icon, iconType, files); 424 } 425 if (retVal != null) { 426 return retVal; 427 } 428 429 430 retVal = icon; 431 FileSystem fs = getDelegateFileSystem(files); 432 if (fs != null) { 433 Set transformedSet = new LazySet (files); 434 retVal = fs.getStatus().annotateIcon(icon, iconType, transformedSet); 435 } 436 437 return retVal; 438 } 439 440 public String annotateName(String name, Set files) { 441 String retVal = null; 442 Iterator it = annotationProviders.allInstances ().iterator (); 443 while (retVal == null && it.hasNext ()) { 444 AnnotationProvider ap = (AnnotationProvider)it.next (); 445 retVal = ap.annotateName (name, files); 446 } 447 if (retVal != null) { 448 return retVal; 449 } 450 retVal = name; 451 452 Set transformedSet = new LazySet (files); 453 FileSystem fs = getDelegateFileSystem(files); 454 if (fs != null) { 455 retVal = fs.getStatus().annotateName(name, transformedSet); 456 } 457 return retVal; 458 } 459 460 public String annotateNameHtml(String name, Set files) { 461 String retVal = null; 462 Iterator it = annotationProviders.allInstances ().iterator (); 463 while (retVal == null && it.hasNext ()) { 464 AnnotationProvider ap = (AnnotationProvider)it.next (); 465 retVal = ap.annotateNameHtml (name, files); 466 } 467 return retVal; 468 } 469 } 470 471 private static final class Replace implements Serializable { 472 static final long serialVersionUID = 50485340814380L; 473 474 public Object readResolve () { 475 return MasterFileSystem.getDefault(); 476 } 477 } 479 final static class LazySet implements Set { 480 private Set obj_files; 481 private boolean initialized = false; 482 private Iterator it = null; 483 484 LazySet(Set obj_files) { 485 this.obj_files = obj_files; 486 } 487 488 synchronized private void lazyInitialization() { 489 if (!initialized) { 490 Set transformedSet = Utils.transformSet(obj_files); 491 obj_files = transformedSet; 492 initialized = true; 493 } 494 } 495 496 public boolean add(Object o) { 497 throw new UnsupportedOperationException (); 498 } 499 500 public boolean addAll(Collection c) { 501 throw new UnsupportedOperationException (); 502 } 503 504 public void clear() { 505 throw new UnsupportedOperationException (); 506 } 507 508 public boolean contains(Object o) { 509 lazyInitialization(); 510 return obj_files.contains(o); 511 } 512 513 public boolean containsAll(Collection c) { 514 lazyInitialization(); 515 return obj_files.containsAll(c); 516 } 517 518 public boolean isEmpty() { 519 lazyInitialization(); 520 return obj_files.isEmpty(); 521 } 522 523 public Iterator iterator() { 524 if (initialized) { 525 it = obj_files.iterator(); 526 } else { 527 it = new Iterator() { 528 private final Iterator originalIterator = obj_files.iterator(); 529 530 public void remove() { 531 throw new UnsupportedOperationException (); 532 } 533 534 public Object next() { 535 MasterFileObject mfo = (MasterFileObject)originalIterator.next(); 536 return mfo.getDelegate().get (true); 537 } 538 539 public boolean hasNext() { 540 return originalIterator.hasNext(); 541 } 542 543 }; 544 } 545 546 return it; 547 } 548 549 public boolean remove(Object o) { 550 lazyInitialization(); 551 return obj_files.remove(o); 552 } 553 554 public boolean removeAll(Collection c) { 555 lazyInitialization(); 556 return obj_files.removeAll(c); 557 } 558 559 public boolean retainAll(Collection c) { 560 lazyInitialization(); 561 return obj_files.retainAll(c); 562 } 563 564 public int size() { 565 lazyInitialization(); 566 return obj_files.size(); 567 } 568 569 public Object [] toArray() { 570 lazyInitialization(); 571 return obj_files.toArray(); 572 } 573 574 public Object [] toArray(Object [] a) { 575 lazyInitialization(); 576 return obj_files.toArray(a); 577 } 578 } 579 } 580 | Popular Tags |