1 19 20 package org.netbeans.modules.subversion; 21 22 import java.io.File ; 23 import java.util.regex.*; 24 import org.netbeans.modules.subversion.client.ExceptionHandler; 25 import org.netbeans.modules.versioning.util.ListenersSupport; 26 import org.netbeans.modules.versioning.util.VersioningListener; 27 import org.netbeans.modules.versioning.util.FlatFolder; 28 import org.netbeans.modules.subversion.util.Context; 29 import org.netbeans.modules.subversion.util.SvnUtils; 30 import org.netbeans.modules.turbo.Turbo; 31 import org.netbeans.modules.turbo.CustomProviders; 32 import org.openide.filesystems.FileUtil; 33 import org.openide.filesystems.FileObject; 34 import org.openide.filesystems.FileStateInvalidException; 35 import org.openide.ErrorManager; 36 import java.util.*; 37 import org.netbeans.modules.subversion.client.SvnClient; 38 import org.openide.filesystems.FileSystem; 39 import org.openide.util.RequestProcessor; 40 import org.tigris.subversion.svnclientadapter.*; 41 import org.tigris.subversion.svnclientadapter.ISVNStatus; 42 43 48 public class FileStatusCache implements ISVNNotifyListener { 49 50 57 public static final Object EVENT_FILE_STATUS_CHANGED = new Object (); 58 59 62 private static final Map<File , FileInformation> NOT_MANAGED_MAP = new NotManagedMap(); 63 64 public static final ISVNStatus REPOSITORY_STATUS_UNKNOWN = null; 65 66 private static final FileInformation FILE_INFORMATION_EXCLUDED = new FileInformation(FileInformation.STATUS_NOTVERSIONED_EXCLUDED, false); 69 private static final FileInformation FILE_INFORMATION_EXCLUDED_DIRECTORY = new FileInformation(FileInformation.STATUS_NOTVERSIONED_EXCLUDED, true); 70 private static final FileInformation FILE_INFORMATION_UPTODATE_DIRECTORY = new FileInformation(FileInformation.STATUS_VERSIONED_UPTODATE, true); 71 private static final FileInformation FILE_INFORMATION_NOTMANAGED = new FileInformation(FileInformation.STATUS_NOTVERSIONED_NOTMANAGED, false); 72 private static final FileInformation FILE_INFORMATION_NOTMANAGED_DIRECTORY = new FileInformation(FileInformation.STATUS_NOTVERSIONED_NOTMANAGED, true); 73 private static final FileInformation FILE_INFORMATION_UNKNOWN = new FileInformation(FileInformation.STATUS_UNKNOWN, false); 74 75 80 private static final Pattern auxConflictPattern = Pattern.compile("(.*?)\\.((r\\d+)|(mine)|" + "(working)|(merge-right\\.r\\d+)|((merge-left.r\\d+)))$"); 83 92 93 private final Turbo turbo; 94 95 101 private final String FILE_STATUS_MAP = DiskMapTurboProvider.ATTR_STATUS_MAP; 102 103 private DiskMapTurboProvider cacheProvider; 104 105 private Subversion svn; 106 107 private Set<FileSystem> filesystemsToRefresh; 108 109 private RequestProcessor.Task refreshFilesystemsTask; 110 111 FileStatusCache() { 112 this.svn = Subversion.getInstance(); 113 cacheProvider = new DiskMapTurboProvider(); 114 turbo = Turbo.createCustom(new CustomProviders() { 115 private final Set providers = Collections.singleton(cacheProvider); 116 public Iterator providers() { 117 return providers.iterator(); 118 } 119 }, 200, 5000); 120 } 121 122 124 133 public File [] listFiles(File dir) { 134 Set<File > files = getScannedFiles(dir).keySet(); 135 return files.toArray(new File [files.size()]); 136 } 137 138 148 public File [] listFiles(Context context, int includeStatus) { 149 Set<File > set = new HashSet<File >(); 150 Map allFiles = cacheProvider.getAllModifiedValues(); 151 for (Iterator i = allFiles.keySet().iterator(); i.hasNext();) { 152 File file = (File ) i.next(); 153 FileInformation info = (FileInformation) allFiles.get(file); 154 if ((info.getStatus() & includeStatus) == 0) continue; 155 File [] roots = context.getRootFiles(); 156 for (int j = 0; j < roots.length; j++) { 157 File root = roots[j]; 158 if (root instanceof FlatFolder) { 159 if (file.equals(root) || file.getParentFile().equals(root)) { 160 set.add(file); 161 break; 162 } 163 } else { 164 if (SvnUtils.isParentOrEqual(root, file)) { 165 set.add(file); 166 break; 167 } 168 } 169 } 170 } 171 if (context.getExclusions().size() > 0) { 172 for (Iterator i = context.getExclusions().iterator(); i.hasNext();) { 173 File excluded = (File ) i.next(); 174 for (Iterator j = set.iterator(); j.hasNext();) { 175 File file = (File ) j.next(); 176 if (SvnUtils.isParentOrEqual(excluded, file)) { 177 j.remove(); 178 } 179 } 180 } 181 } 182 return set.toArray(new File [set.size()]); 183 } 184 185 195 public File [] listFiles(File [] roots, int includeStatus) { 196 Set<File > set = new HashSet<File >(); 197 Map allFiles = cacheProvider.getAllModifiedValues(); 198 for (Iterator i = allFiles.keySet().iterator(); i.hasNext();) { 199 File file = (File ) i.next(); 200 FileInformation info = (FileInformation) allFiles.get(file); 201 if ((info.getStatus() & includeStatus) == 0) continue; 202 for (int j = 0; j < roots.length; j++) { 203 File root = roots[j]; 204 if (root instanceof FlatFolder) { 205 if (file.getParentFile().equals(root)) { 206 set.add(file); 207 break; 208 } 209 } else { 210 if (SvnUtils.isParentOrEqual(root, file)) { 211 set.add(file); 212 break; 213 } 214 } 215 } 216 } 217 return set.toArray(new File [set.size()]); 218 } 219 220 227 public FileInformation getStatus(File file) { 228 if (svn.isAdministrative(file)) return FILE_INFORMATION_NOTMANAGED_DIRECTORY; 229 File dir = file.getParentFile(); 230 if (dir == null) { 231 return FILE_INFORMATION_NOTMANAGED; } 233 Map files = getScannedFiles(dir); 234 if (files == NOT_MANAGED_MAP) return FILE_INFORMATION_NOTMANAGED; 235 FileInformation fi = (FileInformation) files.get(file); 236 if (fi != null) { 237 return fi; 238 } 239 if (!exists(file)) return FILE_INFORMATION_UNKNOWN; 240 if (file.isDirectory()) { 241 return refresh(file, REPOSITORY_STATUS_UNKNOWN); 242 } else { 243 return new FileInformation(FileInformation.STATUS_VERSIONED_UPTODATE, false); 244 } 245 } 246 247 253 FileInformation getCachedStatus(File file) { 254 file = file.getParentFile(); 255 if (file == null) return FILE_INFORMATION_NOTMANAGED_DIRECTORY; 256 Map<File , FileInformation> files = (Map<File , FileInformation>) turbo.readEntry(file, FILE_STATUS_MAP); 257 return files != null ? files.get(file) : null; 258 } 259 260 private FileInformation refresh(File file, ISVNStatus repositoryStatus, boolean forceChangeEvent) { 261 File dir = file.getParentFile(); 262 if (dir == null) { 263 return FILE_INFORMATION_NOTMANAGED; } 265 Map<File , FileInformation> files = getScannedFiles(dir); 266 if (files == NOT_MANAGED_MAP && repositoryStatus == REPOSITORY_STATUS_UNKNOWN) return FILE_INFORMATION_NOTMANAGED; 267 FileInformation current = files.get(file); 268 269 ISVNStatus status = null; 270 try { 271 SvnClient client = Subversion.getInstance().getClient(false); 272 status = client.getSingleStatus(file); 273 if (status != null && SVNStatusKind.UNVERSIONED.equals(status.getTextStatus())) { 274 status = null; 275 } 276 } catch (SVNClientException e) { 277 if (ExceptionHandler.isUnversionedResource(e.getMessage()) == false) { 282 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 285 } 286 } 287 FileInformation fi = createFileInformation(file, status, repositoryStatus); 288 if (equivalent(fi, current)) { 289 if (forceChangeEvent) fireFileStatusChanged(file, current, fi); 290 return fi; 291 } 292 if (current == null && !fi.isDirectory() && fi.getStatus() == FileInformation.STATUS_VERSIONED_UPTODATE) { 294 if (forceChangeEvent) fireFileStatusChanged(file, current, fi); 295 return fi; 296 } 297 298 file = FileUtil.normalizeFile(file); 299 dir = FileUtil.normalizeFile(dir); 300 Map<File , FileInformation> newFiles = new HashMap<File , FileInformation>(files); 301 if (fi.getStatus() == FileInformation.STATUS_UNKNOWN) { 302 newFiles.remove(file); 303 turbo.writeEntry(file, FILE_STATUS_MAP, null); } 305 else if (fi.getStatus() == FileInformation.STATUS_VERSIONED_UPTODATE && file.isFile()) { 306 newFiles.remove(file); 307 } else { 308 newFiles.put(file, fi); 309 } 310 assert newFiles.containsKey(dir) == false; 311 turbo.writeEntry(dir, FILE_STATUS_MAP, newFiles.size() == 0 ? null : newFiles); 312 313 if (file.isDirectory() && needRecursiveRefresh(fi, current)) { 314 File [] content = listFiles(file); 315 for (int i = 0; i < content.length; i++) { 316 refresh(content[i], REPOSITORY_STATUS_UNKNOWN); 317 } 318 } 319 fireFileStatusChanged(file, current, fi); 320 return fi; 321 } 322 323 334 public FileInformation refresh(File file, ISVNStatus repositoryStatus) { 335 return refresh(file, repositoryStatus, false); 336 } 337 338 345 private static boolean equivalent(FileInformation main, FileInformation other) { 346 if (other == null || main.getStatus() != other.getStatus() || main.isDirectory() != other.isDirectory()) return false; 347 348 ISVNStatus e1 = main.getEntry(null); 349 ISVNStatus e2 = other.getEntry(null); 350 return e1 == e2 || e1 == null || e2 == null || equal(e1, e2); 351 } 352 353 360 private static boolean equal(ISVNStatus e1, ISVNStatus e2) { 361 long r1 = -1; 362 if (e1 != null) { 363 SVNRevision r = e1.getRevision(); 364 r1 = r != null ? e1.getRevision().getNumber() : r1; 365 } 366 367 long r2 = -2; 368 if (e2 != null) { 369 SVNRevision r = e1.getRevision(); 370 r2 = r != null ? e2.getRevision().getNumber() : r2; 371 } 372 373 if ( r1 != r2 ) { 374 return false; 375 } 376 return e1.getUrl() == e2.getUrl() || 377 e1.getUrl() != null && e1.getUrl().equals(e2.getUrl()); 378 } 379 380 private boolean needRecursiveRefresh(FileInformation fi, FileInformation current) { 381 if (fi.getStatus() == FileInformation.STATUS_NOTVERSIONED_EXCLUDED || 382 current != null && current.getStatus() == FileInformation.STATUS_NOTVERSIONED_EXCLUDED) return true; 383 if (fi.getStatus() == FileInformation.STATUS_NOTVERSIONED_NOTMANAGED || 384 current != null && current.getStatus() == FileInformation.STATUS_NOTVERSIONED_NOTMANAGED) return true; 385 return false; 386 } 387 388 395 public void refreshCached(File file, ISVNStatus repositoryStatus) { 396 refresh(file, repositoryStatus); 397 } 398 399 405 public void refreshCached(Context ctx) { 406 407 File [] files = listFiles(ctx, ~0); 408 409 for (int i = 0; i < files.length; i++) { 410 File file = files[i]; 411 refreshCached(file, REPOSITORY_STATUS_UNKNOWN); 412 } 413 } 414 415 417 Map<File , FileInformation> getAllModifiedFiles() { 418 return cacheProvider.getAllModifiedValues(); 419 } 420 421 426 void directoryContentChanged(File dir) { 427 Map originalFiles = (Map) turbo.readEntry(dir, FILE_STATUS_MAP); 428 if (originalFiles != null) { 429 for (Iterator i = originalFiles.keySet().iterator(); i.hasNext();) { 430 File file = (File ) i.next(); 431 refresh(file, REPOSITORY_STATUS_UNKNOWN); 432 } 433 } 434 } 435 436 439 void cleanUp() { 440 Map files = cacheProvider.getAllModifiedValues(); 441 for (Iterator i = files.keySet().iterator(); i.hasNext();) { 442 File file = (File ) i.next(); 443 FileInformation info = (FileInformation) files.get(file); 444 if ((info.getStatus() & FileInformation.STATUS_LOCAL_CHANGE) != 0) { 445 refresh(file, REPOSITORY_STATUS_UNKNOWN); 446 } else if (info.getStatus() == FileInformation.STATUS_NOTVERSIONED_EXCLUDED) { 447 if (!exists(file)) { 450 refresh(file, REPOSITORY_STATUS_UNKNOWN); 451 } 452 } 453 } 454 } 455 456 458 private Map<File , FileInformation> getScannedFiles(File dir) { 459 Map<File , FileInformation> files; 460 461 463 if (svn.isAdministrative(dir)) { 464 return NOT_MANAGED_MAP; 465 } 466 File parent = dir.getParentFile(); 467 if (parent != null && svn.isAdministrative(parent)) { 468 return NOT_MANAGED_MAP; 469 } 470 471 files = (Map<File , FileInformation>) turbo.readEntry(dir, FILE_STATUS_MAP); 472 if (files != null) return files; 473 if (isNotManagedByDefault(dir)) { 474 return NOT_MANAGED_MAP; 475 } 476 477 479 dir = FileUtil.normalizeFile(dir); 480 files = scanFolder(dir); assert files.containsKey(dir) == false; 482 turbo.writeEntry(dir, FILE_STATUS_MAP, files); 483 for (Iterator i = files.keySet().iterator(); i.hasNext();) { 484 File file = (File ) i.next(); 485 FileInformation info = files.get(file); 486 if ((info.getStatus() & FileInformation.STATUS_LOCAL_CHANGE) != 0) { 487 fireFileStatusChanged(file, null, info); 488 } 489 } 490 return files; 491 } 492 493 private boolean isNotManagedByDefault(File dir) { 494 return !dir.exists(); 495 } 496 497 503 private Map<File , FileInformation> scanFolder(File dir) { 504 File [] files = dir.listFiles(); 505 if (files == null) files = new File [0]; 506 Map<File , FileInformation> folderFiles = new HashMap<File , FileInformation>(files.length); 507 508 ISVNStatus [] entries = null; 509 try { 510 SvnClient client = Subversion.getInstance().getClient(true); 511 if (Subversion.getInstance().isManaged(dir)) { 512 entries = client.getStatus(dir, false, false); 513 } 514 } catch (SVNClientException e) { 515 ErrorManager.getDefault().annotate(e, "Can not status " + dir.getAbsolutePath() + ", guessing it..."); ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 518 } 519 520 if (entries == null) { 521 for (int i = 0; i < files.length; i++) { 522 File file = files[i]; 523 if (svn.isAdministrative(file)) continue; 524 FileInformation fi = createFileInformation(file, null, REPOSITORY_STATUS_UNKNOWN); 525 if (fi.isDirectory() || fi.getStatus() != FileInformation.STATUS_VERSIONED_UPTODATE) { 526 folderFiles.put(file, fi); 527 } 528 } 529 } else { 530 Set<File > localFiles = new HashSet<File >(Arrays.asList(files)); 531 for (int i = 0; i < entries.length; i++) { 532 ISVNStatus entry = entries[i]; 533 File file = new File (entry.getPath()); 534 if (file.equals(dir)) { 535 continue; 536 } 537 localFiles.remove(file); 538 if (svn.isAdministrative(file)) { 539 continue; 540 } 541 FileInformation fi = createFileInformation(file, entry, REPOSITORY_STATUS_UNKNOWN); 542 if (fi.isDirectory() || fi.getStatus() != FileInformation.STATUS_VERSIONED_UPTODATE) { 543 folderFiles.put(file, fi); 544 } 545 } 546 547 Iterator it = localFiles.iterator(); 548 while (it.hasNext()) { 549 File localFile = (File ) it.next(); 550 FileInformation fi = createFileInformation(localFile, null, REPOSITORY_STATUS_UNKNOWN); 551 if (fi.isDirectory() || fi.getStatus() != FileInformation.STATUS_VERSIONED_UPTODATE) { 552 folderFiles.put(localFile, fi); 553 } 554 } 555 } 556 557 return folderFiles; 558 } 559 560 566 private FileInformation createFileInformation(File file, ISVNStatus status, ISVNStatus repositoryStatus) { 567 if (status == null || status.getTextStatus().equals(SVNStatusKind.UNVERSIONED)) { 568 if (!svn.isManaged(file)) { 569 return file.isDirectory() ? FILE_INFORMATION_NOTMANAGED_DIRECTORY : FILE_INFORMATION_NOTMANAGED; 570 } 571 return createMissingEntryFileInformation(file, repositoryStatus); 572 } else { 573 return createVersionedFileInformation(file, status, repositoryStatus); 574 } 575 } 576 577 584 private FileInformation createVersionedFileInformation(File file, ISVNStatus status, ISVNStatus repositoryStatus) { 585 586 SVNStatusKind kind = status.getTextStatus(); 587 SVNStatusKind pkind = status.getPropStatus(); 588 589 int remoteStatus = 0; 590 if (repositoryStatus != REPOSITORY_STATUS_UNKNOWN) { 591 if (repositoryStatus.getRepositoryTextStatus() == SVNStatusKind.MODIFIED 592 || repositoryStatus.getRepositoryPropStatus() == SVNStatusKind.MODIFIED) { 593 remoteStatus = FileInformation.STATUS_VERSIONED_MODIFIEDINREPOSITORY; 594 } else if (repositoryStatus.getRepositoryTextStatus() == SVNStatusKind.DELETED 595 ) { 596 remoteStatus = FileInformation.STATUS_VERSIONED_REMOVEDINREPOSITORY; 597 } else if (repositoryStatus.getRepositoryTextStatus() == SVNStatusKind.ADDED 598 ) { 599 } else if (repositoryStatus.getRepositoryTextStatus() == null 601 && repositoryStatus.getRepositoryPropStatus() == null) { 602 } else { 604 System.err.println("SVN.FSC: unhandled repository status: " + file.getAbsolutePath()); System.err.println("\ttext: " + repositoryStatus.getRepositoryTextStatus()); System.err.println("\tprop: " + repositoryStatus.getRepositoryPropStatus()); } 611 } 612 613 if (SVNStatusKind.NONE.equals(pkind)) { 614 } else if (SVNStatusKind.NORMAL.equals(pkind)) { 616 } else if (SVNStatusKind.MODIFIED.equals(pkind)) { 618 if (SVNStatusKind.NORMAL.equals(kind)) { 619 return new FileInformation(FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY | remoteStatus, status); 620 } 621 } else if (SVNStatusKind.CONFLICTED.equals(pkind)) { 622 return new FileInformation(FileInformation.STATUS_VERSIONED_CONFLICT | remoteStatus, status); 623 } else { 624 throw new IllegalArgumentException ("Unknown prop status: " + status.getPropStatus()); } 626 627 628 if (SVNStatusKind.NONE.equals(kind)) { 629 return FILE_INFORMATION_UNKNOWN; 630 } else if (SVNStatusKind.NORMAL.equals(kind)) { 631 return new FileInformation(FileInformation.STATUS_VERSIONED_UPTODATE | remoteStatus, status); 632 } else if (SVNStatusKind.MODIFIED.equals(kind)) { 633 return new FileInformation(FileInformation.STATUS_VERSIONED_MODIFIEDLOCALLY | remoteStatus, status); 634 } else if (SVNStatusKind.ADDED.equals(kind)) { 635 return new FileInformation(FileInformation.STATUS_VERSIONED_ADDEDLOCALLY | remoteStatus, status); 636 } else if (SVNStatusKind.DELETED.equals(kind)) { 637 return new FileInformation(FileInformation.STATUS_VERSIONED_REMOVEDLOCALLY | remoteStatus, status); 638 } else if (SVNStatusKind.UNVERSIONED.equals(kind)) { 639 return new FileInformation(FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY | remoteStatus, status); 640 } else if (SVNStatusKind.MISSING.equals(kind)) { 641 return new FileInformation(FileInformation.STATUS_VERSIONED_DELETEDLOCALLY | remoteStatus, status); 642 } else if (SVNStatusKind.REPLACED.equals(kind)) { 643 return new FileInformation(FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY | remoteStatus, status); 646 } else if (SVNStatusKind.MERGED.equals(kind)) { 647 return new FileInformation(FileInformation.STATUS_VERSIONED_MERGE | remoteStatus, status); 648 } else if (SVNStatusKind.CONFLICTED.equals(kind)) { 649 return new FileInformation(FileInformation.STATUS_VERSIONED_CONFLICT | remoteStatus, status); 650 } else if (SVNStatusKind.OBSTRUCTED.equals(kind)) { 651 return new FileInformation(FileInformation.STATUS_VERSIONED_CONFLICT | remoteStatus, status); 653 } else if (SVNStatusKind.IGNORED.equals(kind)) { 654 return new FileInformation(FileInformation.STATUS_NOTVERSIONED_EXCLUDED | remoteStatus, status); 655 } else if (SVNStatusKind.INCOMPLETE.equals(kind)) { 656 return new FileInformation(FileInformation.STATUS_VERSIONED_CONFLICT | remoteStatus, status); 658 } else if (SVNStatusKind.EXTERNAL.equals(kind)) { 659 return new FileInformation(FileInformation.STATUS_VERSIONED_UPTODATE | remoteStatus, status); 661 } else { 662 throw new IllegalArgumentException ("Unknown text status: " + status.getTextStatus()); } 664 } 665 666 static String statusText(ISVNStatus status) { 667 return "file: " + status.getTextStatus().toString() + " copied: " + status.isCopied() + " prop: " + status.getPropStatus().toString(); } 669 670 676 private FileInformation createMissingEntryFileInformation(File file, ISVNStatus repositoryStatus) { 677 678 boolean isDirectory = file.isDirectory(); 680 int parentStatus = getStatus(file.getParentFile()).getStatus(); 681 if (parentStatus == FileInformation.STATUS_NOTVERSIONED_EXCLUDED) { 682 return isDirectory ? 683 FILE_INFORMATION_EXCLUDED_DIRECTORY : FILE_INFORMATION_EXCLUDED; 684 } 685 if (parentStatus == FileInformation.STATUS_NOTVERSIONED_NOTMANAGED) { 686 if (isDirectory) { 687 return SvnUtils.isPartOfSubversionMetadata(file) ? 689 FILE_INFORMATION_NOTMANAGED_DIRECTORY : FILE_INFORMATION_UPTODATE_DIRECTORY; 690 } else { 691 return FILE_INFORMATION_NOTMANAGED; 692 } 693 } 694 695 711 String name = file.getName(); 712 Matcher m = auxConflictPattern.matcher(name); 713 if (m.matches()) { 714 File dir = file.getParentFile(); 715 if (dir != null) { 716 String masterName = m.group(1); 717 File master = new File (dir, masterName); 718 if (master.isFile()) { 719 return FILE_INFORMATION_EXCLUDED; 720 } 721 } 722 } 723 724 if (file.exists()) { 725 if (Subversion.getInstance().isIgnored(file)) { 726 return new FileInformation(FileInformation.STATUS_NOTVERSIONED_EXCLUDED, file.isDirectory()); 727 } else { 728 return new FileInformation(FileInformation.STATUS_NOTVERSIONED_NEWLOCALLY, file.isDirectory()); 729 } 730 } else { 731 if (repositoryStatus != REPOSITORY_STATUS_UNKNOWN) { 732 if (repositoryStatus.getRepositoryTextStatus() == SVNStatusKind.ADDED) { 733 boolean folder = repositoryStatus.getNodeKind() == SVNNodeKind.DIR; 734 return new FileInformation(FileInformation.STATUS_VERSIONED_NEWINREPOSITORY, folder); 735 } 736 } 737 return FILE_INFORMATION_UNKNOWN; 738 } 739 } 740 741 private boolean exists(File file) { 742 if (!file.exists()) return false; 743 return file.getAbsolutePath().equals(FileUtil.normalizeFile(file).getAbsolutePath()); 744 } 745 746 ListenersSupport listenerSupport = new ListenersSupport(this); 747 public void addVersioningListener(VersioningListener listener) { 748 listenerSupport.addListener(listener); 749 } 750 751 public void removeVersioningListener(VersioningListener listener) { 752 listenerSupport.removeListener(listener); 753 } 754 755 private void fireFileStatusChanged(File file, FileInformation oldInfo, FileInformation newInfo) { 756 listenerSupport.fireVersioningEvent(EVENT_FILE_STATUS_CHANGED, new Object [] { file, oldInfo, newInfo }); 757 } 758 759 public void setCommand(int command) { 760 } 762 763 public void logCommandLine(String commandLine) { 764 } 766 767 public void logMessage(String message) { 768 } 770 771 public void logError(String message) { 772 } 774 775 public void logRevision(long revision, String path) { 776 } 778 779 public void logCompleted(String message) { 780 } 782 783 public void onNotify(File path, SVNNodeKind kind) { 784 785 if (path == null) { return; 787 } 788 789 path = FileUtil.normalizeFile(path); 791 792 refresh(path, REPOSITORY_STATUS_UNKNOWN, true); 796 797 for (;;) { 799 FileObject fo = FileUtil.toFileObject(path); 800 if (fo != null) { 801 try { 802 Set<FileSystem> filesystems = getFilesystemsToRefresh(); 803 synchronized (filesystems) { 804 filesystems.add(fo.getFileSystem()); 805 } 806 } catch (FileStateInvalidException e) { 807 } 809 break; 810 } else { 811 path = path.getParentFile(); 812 if (path == null) break; 813 } 814 } 815 } 816 817 public void refreshDirtyFileSystems() { 818 if(refreshFilesystemsTask == null) { 819 RequestProcessor rp = new RequestProcessor(); 820 refreshFilesystemsTask = rp.create(new Runnable () { 821 public void run() { 822 Set<FileSystem> filesystems = getFilesystemsToRefresh(); 823 FileSystem[] filesystemsToRefresh = new FileSystem[filesystems.size()]; 824 synchronized (filesystems) { 825 filesystemsToRefresh = filesystems.toArray(new FileSystem[filesystems.size()]); 826 filesystems.clear(); 827 } 828 for (int i = 0; i < filesystemsToRefresh.length; i++) { 829 filesystemsToRefresh[i].refresh(true); 831 } 832 } 833 }); 834 } 835 refreshFilesystemsTask.schedule(200); 836 } 837 838 private Set<FileSystem> getFilesystemsToRefresh() { 839 if(filesystemsToRefresh == null) { 840 filesystemsToRefresh = new HashSet<FileSystem>(); 841 } 842 return filesystemsToRefresh; 843 } 844 845 private static final class NotManagedMap extends AbstractMap<File , FileInformation> { 846 public Set<Entry<File , FileInformation>> entrySet() { 847 return Collections.emptySet(); 848 } 849 } 850 } 851 | Popular Tags |