1 19 20 package org.netbeans.modules.masterfs; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.Arrays ; 26 import java.util.Collections ; 27 import java.util.Enumeration ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.LinkedHashSet ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Set ; 34 import java.util.WeakHashMap ; 35 import javax.swing.filechooser.FileSystemView ; 36 import org.netbeans.modules.masterfs.filebasedfs.FileBasedFileSystem; 37 import org.openide.filesystems.FileChangeListener; 38 import org.openide.filesystems.FileEvent; 39 import org.openide.filesystems.FileObject; 40 import org.openide.filesystems.FileStateInvalidException; 41 import org.openide.filesystems.FileSystem; 42 import org.openide.util.Utilities; 43 import org.openide.util.actions.SystemAction; 44 45 51 final class SpecialDelegates { 52 private static boolean isUnixRootResolved = false; 53 private static FileSystem fs = new WinSpecialFs(); 54 private static final FileSystemView fsv = FileSystemView.getFileSystemView(); 55 56 private SpecialDelegates() { 57 } 58 59 70 static FileObject get(final ResourcePath resPath) { 71 FileObject retVal; 72 if ((Utilities.isWindows () || (Utilities.getOperatingSystem () == Utilities.OS_OS2))) 73 retVal = getForWindows(resPath); 74 else if (Utilities.getOperatingSystem() == Utilities.OS_VMS) 75 retVal = getForVMS(resPath); 76 else { 77 retVal = getForUnix(resPath); 78 } 79 return retVal; 81 } 82 83 88 private static FileObject getForUnix(final ResourcePath resPath) { 89 FileObject retVal = null; 90 if (!isUnixRootResolved) { 91 mountUnixRoot(); 92 retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath()); 93 isUnixRootResolved = true; 94 } 95 return retVal; 96 } 97 98 103 private static FileObject getForVMS(final ResourcePath resPath) { 104 FileObject retVal = null; 105 mountVMSRoot(resPath); 106 retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath()); 107 return retVal; 108 } 109 110 private static FileObject getForWindows(final ResourcePath resPath) { 111 FileObject retVal = null; 112 if (resPath.isRoot()) 113 retVal = WinRootVirtual.getDefault(); 114 else if (isWinDrive(resPath)) 115 retVal = WindowsDriveProxy.getDefault(resPath); 116 else { 117 WindowsDriveProxy winDrive = WindowsDriveProxy.getDefault(resPath); 118 if (winDrive != null && !winDrive.isMounted()) { 119 winDrive.lfs = mountWinDrive(winDrive.getResource()); 120 retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath()); 122 } 123 } 124 return retVal; 125 } 126 127 private static boolean isWinDrive(final ResourcePath resPath) { 129 boolean root = resPath.getParent().isRoot(); 130 if (root) { 131 root = (checkValidWindowsDrive (resPath.getFile()) != null); 132 } 133 return root; 134 } 135 136 private static FileSystem mountWinDrive(final ResourcePath mountPointPath) { 137 FileSystem retVal = null; 138 final String rootPath = mountPointPath.getNormalizedPath().substring(1) + "/"; 139 final File root = checkValidWindowsDrive(new File (rootPath)); 140 if (root != null) { 141 retVal = mountLocalFileSystem(root, rootPath); 142 } 143 return retVal; 144 } 145 146 private static void mountUnixRoot() { 147 final String rootPath = ResourcePath.getRoot().getNormalizedPath(); 148 final File root = new File (rootPath); 149 if (root.exists()) 150 mountLocalFileSystem(root, rootPath); 151 } 152 153 156 private static void mountVMSRoot(final ResourcePath mountPointPath) { 157 final String rootPath = mountPointPath.getNormalizedPath(); 161 final File root = new File (rootPath); 162 if (root.exists()) 163 mountLocalFileSystem(root, rootPath); 164 165 } 166 167 private static FileSystem mountLocalFileSystem(final File root, final String rootPath) { 168 FileSystem retVal; 169 try { 171 retVal = FileBasedFileSystem.getInstance(root); 174 MountTable.getDefault().mount(rootPath, retVal); 175 } catch (IOException e) { 176 retVal = null; 177 } 178 return retVal; 179 } 180 181 static File checkValidWindowsDrive(final File root) { 182 File retVal = null; 183 if (fsv != null) { 184 185 retVal = ((isRoot(root) || (fsv.isFileSystemRoot(root))) && !fsv.isFloppyDrive(root)) ? root : null; 186 187 188 if (retVal != null && !retVal.exists()) { 189 retVal = null; 190 } 191 } else { 192 retVal = isRoot(root) ? root : null; 193 } 194 195 return retVal; 196 } 197 198 private static boolean isRoot(final File root) { 199 boolean retval = false; 200 if (root.getParentFile() == null) { 201 File [] allFiles = File.listRoots(); 202 for (int i = 0; i < allFiles.length; i++) { 203 File windowsDrive = allFiles[i]; 204 if (windowsDrive.equals(root)) { 205 retval = true; 206 break; 207 } 208 } 209 } 210 return retval; 211 } 212 213 private static File [] listRoots() { 214 File [] all = File.listRoots(); 215 216 if ((Utilities.isWindows () || (Utilities.getOperatingSystem () == Utilities.OS_OS2)) && fsv != null) { 217 Set roots = new LinkedHashSet (); 218 219 for (int i = 0; i < all.length; i++) { 220 File file = checkValidWindowsDrive(all[i]); 221 if (file != null) { 222 roots.add(file); 223 } 224 } 225 all = new File [roots.size()]; 226 roots.toArray(all); 227 } 228 return all; 229 } 230 231 234 static class WinRootVirtual extends InvalidDummy { 235 236 static final long serialVersionUID = -1244651321879256809L; 237 transient private static WinRootVirtual instance = null; 238 transient private static ArrayList delegs = null; 239 transient private Set listenerList; 241 242 private static WinRootVirtual getDefault() { 243 synchronized (WinRootVirtual.class) { 244 if (instance == null) 245 instance = new WinRootVirtual(new ResourcePath("")); 246 } 247 return instance; 248 } 249 250 private WinRootVirtual(final ResourcePath resPath) { 251 super(resPath); 252 } 253 254 public void addFileChangeListener(FileChangeListener fcl) { 255 getListenerList().add(fcl); 256 } 257 258 public void removeFileChangeListener(FileChangeListener fcl) { 259 getListenerList().remove(fcl); 260 } 261 262 public FileSystem getFileSystem() throws FileStateInvalidException { 263 return fs; 264 } 265 266 public boolean isRoot() { 267 return true; 268 } 269 270 public boolean isFolder() { 271 return true; 272 } 273 274 public boolean isData() { 275 return false; 276 } 277 278 public void refresh(final boolean expected) { 279 List oldFos = Arrays.asList(getChildren()); 280 delegs = null; 281 List newFos = Arrays.asList(getChildren()); 282 Set removeSet = new HashSet (oldFos); 283 Set addSet = new HashSet (newFos); 284 285 removeSet.removeAll(newFos); 286 addSet.removeAll(oldFos); 287 288 289 for (Iterator iterator = removeSet.iterator(); iterator.hasNext();) { 290 FileObject fo = (FileObject) iterator.next(); 291 FileEvent fe = new FileEvent(this, fo); 292 fireFileDeletedEvent(Collections.enumeration(getListenerList()), fe); 294 } 295 296 for (Iterator iterator = addSet.iterator(); iterator.hasNext();) { 297 FileObject fo = (FileObject) iterator.next(); 298 299 FileEvent fe = new FileEvent(this, fo); 300 if (fo.isFolder()) 301 fireFileFolderCreatedEvent(Collections.enumeration(getListenerList()), fe); 302 else 303 fireFileDataCreatedEvent(Collections.enumeration(getListenerList()), fe); 304 } 305 } 306 307 public FileObject[] getChildren() { 308 synchronized (WinRootVirtual.class) { 309 if (delegs == null) { 310 List roots = Arrays.asList(listRoots()); 311 delegs = new ArrayList (); 312 for (int i = 0; i < roots.size(); i++) { 313 File root = (File ) roots.get(i); 314 ResourcePath resName = getResource().getChild(root.getAbsolutePath()); 315 WindowsDriveProxy winDrive = WindowsDriveProxy.getDefault(resName); 316 if (winDrive != null) { 317 delegs.add(winDrive); } 319 } 320 } 321 } 322 323 FileObject[] retVal = new FileObject[delegs.size()]; 324 delegs.toArray(retVal); 325 return retVal; 326 } 327 328 public boolean isValid() { 329 return true; 330 } 331 332 public FileObject getFileObject(String name, String ext) { 333 FileObject retVal = null; 334 FileObject[] chlds = getChildren(); 335 for (int i = 0; i < chlds.length; i++) { 336 FileObject chld = chlds[i]; 337 if (chld.getName().equals(name) && chld.getExt().equals(ext)) { 338 retVal = chld; 339 break; 340 } 341 } 342 return retVal; 343 } 344 345 Set getListenerList() { 346 synchronized (WindowsDriveProxy.class) { 347 if (listenerList == null) { 348 listenerList = Collections.synchronizedSet(new HashSet ()); 349 } 350 } 351 return listenerList; 352 } 353 } 354 355 358 private static final class WindowsDriveProxy extends WinRootVirtual { 359 360 static final long serialVersionUID = -1244651321879256718L; 361 transient private FileObject delegate; 362 transient private boolean isValid = true; 363 364 transient private static final Map instances = new WeakHashMap (); 365 transient private FileSystem lfs; 366 367 368 private static WindowsDriveProxy getDefault(ResourcePath resPath) { 369 WindowsDriveProxy in; 370 String winDrivePath = getWindowsDriveSubstr(resPath.getNormalizedPath()); 371 if (winDrivePath == null) return null; 372 373 resPath = new ResourcePath(winDrivePath); 374 synchronized (WindowsDriveProxy.class) { 375 in = (WindowsDriveProxy) instances.get(resPath); 376 if (in == null) { 377 in = new WindowsDriveProxy(resPath); 378 instances.put(in.getResource(), in); 379 } 380 } 381 return in; 382 } 383 384 385 private static String getWindowsDriveSubstr(String resPath) { 386 int idx = resPath.indexOf(':'); 387 return (idx == -1) ? null : resPath.substring(0, idx + 1); 388 } 389 390 391 private WindowsDriveProxy(ResourcePath resPath) { 392 super(resPath); 393 } 394 395 public boolean isRoot() { 396 return false; 397 } 398 399 public boolean isFolder() { 400 return true; 401 } 402 403 public boolean isData() { 404 return false; 405 } 406 407 public boolean isValid() { 408 return isValid; 409 } 410 411 public FileObject[] getChildren() { 412 FileObject deleg = getDelegate(true); 413 return (deleg != null) ? deleg.getChildren() : new FileObject [] {}; 414 } 415 416 public FileObject getFileObject(String name, String ext) { 417 FileObject deleg = getDelegate(true); 418 return (deleg != null) ? deleg.getFileObject(name, ext) : null; 419 } 420 421 public FileObject getParent() { 422 return WinRootVirtual.getDefault(); 423 } 424 425 private FileObject getDelegate() { 426 return getDelegate(false); 427 } 428 429 private FileObject getDelegate(boolean create) { 430 if (delegate == null && create ) { 431 432 delegate = new InvalidDummy(getResource()); 433 lfs = mountWinDrive(getResource()); 434 delegate = MountTable.getDefault().resolveBestDelegate(getResource().getNormalizedPath()); 435 if (delegate != null) { 436 synchronized (getListenerList()) { 437 Iterator it = getListenerList().iterator(); 438 while (it.hasNext()) { 439 FileChangeListener fcl = (FileChangeListener) it.next(); 440 delegate.addFileChangeListener(fcl); 441 it.remove(); 442 443 } 444 } 445 } else { 446 isValid = false; 447 } 448 } 449 return delegate; 450 } 451 452 public FileSystem getFileSystem() throws FileStateInvalidException { 453 return (lfs != null) ? lfs : fs; 454 } 455 456 457 public FileObject createFolder(String name) throws IOException { 458 return (getDelegate() != null) ? getDelegate().createFolder(name) : 459 super.createFolder(name); 460 } 461 462 public FileObject createData(String name, String ext) throws IOException { 463 return (getDelegate() != null) ? getDelegate().createData(name) : 464 super.createData(name); 465 } 466 467 468 public Object getAttribute(String attrName) { 469 return (getDelegate() != null) ? getDelegate().getAttribute(attrName) : 470 super.getAttribute(attrName); 471 } 472 473 public void setAttribute(String attrName, Object value) throws IOException { 474 if (getDelegate() != null) 475 getDelegate().setAttribute(attrName, value); 476 else 477 super.setAttribute(attrName, value); 478 } 479 480 public Enumeration getAttributes() { 481 return (getDelegate() != null) ? getDelegate().getAttributes() : 482 super.getAttributes(); 483 } 484 485 public void addFileChangeListener(FileChangeListener fcl) { 486 if (getDelegate() != null) 487 getDelegate().addFileChangeListener(fcl); 488 else 489 super.addFileChangeListener(fcl); 490 } 491 492 public void removeFileChangeListener(FileChangeListener fcl) { 493 if (getDelegate() != null) 494 getDelegate().removeFileChangeListener(fcl); 495 else 496 super.removeFileChangeListener(fcl); 497 } 498 499 private boolean isMounted() { 500 return lfs != null; 501 } 502 } 503 504 private static final class WinSpecialFs extends FileSystem { 505 public boolean isReadOnly() { 506 return false; 507 } 508 509 public FileObject getRoot() { 510 return WinRootVirtual.getDefault(); 511 } 512 513 public FileObject findResource(String name) { 514 ResourcePath resPath = new ResourcePath(name); 515 if (resPath.isRoot()) return getRoot(); 516 return WindowsDriveProxy.getDefault(resPath); 517 } 518 519 public SystemAction[] getActions() { 520 return new SystemAction[] {}; 521 } 522 523 public SystemAction[] getActions(Set foSet) { 524 return getActions(); 525 } 526 527 public String getDisplayName() { 528 return null; 529 } 530 } 531 532 } 533 | Popular Tags |