1 11 package org.eclipse.ui.editors.text; 12 13 import java.io.File ; 14 import java.lang.reflect.InvocationTargetException ; 15 import java.net.URI ; 16 import java.util.ArrayList ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.List ; 21 import java.util.Map ; 22 import java.util.NoSuchElementException ; 23 24 import org.osgi.framework.Bundle; 25 26 import org.eclipse.core.filesystem.EFS; 27 import org.eclipse.core.filesystem.IFileInfo; 28 import org.eclipse.core.filesystem.IFileStore; 29 30 import org.eclipse.core.runtime.Assert; 31 import org.eclipse.core.runtime.CoreException; 32 import org.eclipse.core.runtime.IAdaptable; 33 import org.eclipse.core.runtime.ILog; 34 import org.eclipse.core.runtime.IPath; 35 import org.eclipse.core.runtime.IProgressMonitor; 36 import org.eclipse.core.runtime.IStatus; 37 import org.eclipse.core.runtime.MultiStatus; 38 import org.eclipse.core.runtime.NullProgressMonitor; 39 import org.eclipse.core.runtime.Platform; 40 import org.eclipse.core.runtime.Status; 41 import org.eclipse.core.runtime.content.IContentType; 42 import org.eclipse.core.runtime.jobs.ISchedulingRule; 43 44 import org.eclipse.core.resources.IFile; 45 import org.eclipse.core.resources.IResource; 46 import org.eclipse.core.resources.IResourceRuleFactory; 47 import org.eclipse.core.resources.IResourceStatus; 48 import org.eclipse.core.resources.IWorkspace; 49 import org.eclipse.core.resources.ResourcesPlugin; 50 51 import org.eclipse.core.filebuffers.FileBuffers; 52 import org.eclipse.core.filebuffers.IFileBuffer; 53 import org.eclipse.core.filebuffers.IFileBufferListener; 54 import org.eclipse.core.filebuffers.IFileBufferManager; 55 import org.eclipse.core.filebuffers.ITextFileBuffer; 56 import org.eclipse.core.filebuffers.ITextFileBufferManager; 57 import org.eclipse.core.filebuffers.LocationKind; 58 59 import org.eclipse.jface.operation.IRunnableContext; 60 import org.eclipse.jface.operation.IRunnableWithProgress; 61 62 import org.eclipse.jface.text.IDocument; 63 import org.eclipse.jface.text.ISynchronizable; 64 import org.eclipse.jface.text.source.IAnnotationModel; 65 66 import org.eclipse.ui.IEditorInput; 67 import org.eclipse.ui.IFileEditorInput; 68 import org.eclipse.ui.IURIEditorInput; 69 import org.eclipse.ui.PlatformUI; 70 import org.eclipse.ui.internal.editors.text.NLSUtility; 71 import org.eclipse.ui.internal.editors.text.UISynchronizationContext; 72 import org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner; 73 import org.eclipse.ui.part.FileEditorInput; 74 import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; 75 import org.eclipse.ui.texteditor.IDocumentProvider; 76 import org.eclipse.ui.texteditor.IDocumentProviderExtension; 77 import org.eclipse.ui.texteditor.IDocumentProviderExtension2; 78 import org.eclipse.ui.texteditor.IDocumentProviderExtension3; 79 import org.eclipse.ui.texteditor.IDocumentProviderExtension4; 80 import org.eclipse.ui.texteditor.IDocumentProviderExtension5; 81 import org.eclipse.ui.texteditor.IElementStateListener; 82 import org.eclipse.ui.texteditor.IElementStateListenerExtension; 83 import org.eclipse.ui.texteditor.ISchedulingRuleProvider; 84 85 86 109 public class TextFileDocumentProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension5, IStorageDocumentProvider, IDocumentProviderExtension4 { 110 111 114 protected static abstract class DocumentProviderOperation implements IRunnableWithProgress, ISchedulingRuleProvider { 115 116 122 protected abstract void execute(IProgressMonitor monitor) throws CoreException; 123 124 127 public void run(IProgressMonitor monitor) throws InvocationTargetException , InterruptedException { 128 try { 129 execute(monitor); 130 } catch (CoreException x) { 131 throw new InvocationTargetException (x); 132 } 133 } 134 135 138 public ISchedulingRule getSchedulingRule() { 139 return ResourcesPlugin.getWorkspace().getRoot(); 140 } 141 } 142 143 146 static protected class NullProvider implements IDocumentProvider, IDocumentProviderExtension, IDocumentProviderExtension2, IDocumentProviderExtension3, IDocumentProviderExtension4, IDocumentProviderExtension5, IStorageDocumentProvider { 147 148 static final private IStatus STATUS_ERROR= new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IStatus.OK, TextEditorMessages.NullProvider_error, null); 149 150 public void connect(Object element) throws CoreException {} 151 public void disconnect(Object element) {} 152 public IDocument getDocument(Object element) { return null; } 153 public void resetDocument(Object element) throws CoreException {} 154 public void saveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException {} 155 public long getModificationStamp(Object element) { return 0; } 156 public long getSynchronizationStamp(Object element) { return 0; } 157 public boolean isDeleted(Object element) { return true; } 158 public boolean mustSaveDocument(Object element) { return false; } 159 public boolean canSaveDocument(Object element) { return false; } 160 public IAnnotationModel getAnnotationModel(Object element) { return null; } 161 public void aboutToChange(Object element) {} 162 public void changed(Object element) {} 163 public void addElementStateListener(IElementStateListener listener) {} 164 public void removeElementStateListener(IElementStateListener listener) {} 165 public boolean isReadOnly(Object element) { return true; } 166 public boolean isModifiable(Object element) { return false; } 167 public void validateState(Object element, Object computationContext) throws CoreException {} 168 public boolean isStateValidated(Object element) { return true; } 169 public void updateStateCache(Object element) throws CoreException {} 170 public void setCanSaveDocument(Object element) {} 171 public IStatus getStatus(Object element) { return STATUS_ERROR; } 172 public void synchronize(Object element) throws CoreException {} 173 public void setProgressMonitor(IProgressMonitor progressMonitor) {} 174 public IProgressMonitor getProgressMonitor() { return new NullProgressMonitor(); } 175 public boolean isSynchronized(Object element) { return true; } 176 public boolean isNotSynchronizedException(Object element, CoreException ex) { return false; } 177 public String getDefaultEncoding() { return null; } 178 public String getEncoding(Object element) { return null; } 179 public void setEncoding(Object element, String encoding) {} 180 public IContentType getContentType(Object element) throws CoreException { return null; } 181 } 182 183 static protected class FileInfo { 184 public Object fElement; 185 public int fCount; 186 public ITextFileBuffer fTextFileBuffer; 187 188 private LocationKind fTextFileBufferLocationKind; 190 191 public IAnnotationModel fModel; 192 public boolean fCachedReadOnlyState; 193 } 194 195 static private class SingleElementIterator implements Iterator { 196 197 private Object fElement; 198 199 public SingleElementIterator(Object element) { 200 fElement= element; 201 } 202 203 206 public boolean hasNext() { 207 return fElement != null; 208 } 209 210 213 public Object next() { 214 if (fElement != null) { 215 Object result= fElement; 216 fElement= null; 217 return result; 218 } 219 throw new NoSuchElementException (); 220 } 221 222 225 public void remove() { 226 throw new UnsupportedOperationException (); 227 } 228 } 229 230 protected class FileBufferListener implements IFileBufferListener { 231 232 public FileBufferListener() { 233 } 234 235 238 public void bufferContentAboutToBeReplaced(IFileBuffer file) { 239 List list= new ArrayList (fElementStateListeners); 240 Iterator e= list.iterator(); 241 while (e.hasNext()) { 242 IElementStateListener l= (IElementStateListener) e.next(); 243 Iterator i= getElements(file); 244 while (i.hasNext()) 245 l.elementContentAboutToBeReplaced(i.next()); 246 } 247 } 248 249 252 public void bufferContentReplaced(IFileBuffer file) { 253 List list= new ArrayList (fElementStateListeners); 254 Iterator e= list.iterator(); 255 while (e.hasNext()) { 256 IElementStateListener l= (IElementStateListener) e.next(); 257 Iterator i= getElements(file); 258 while (i.hasNext()) 259 l.elementContentReplaced(i.next()); 260 } 261 } 262 263 266 public void stateChanging(IFileBuffer file) { 267 Iterator i= getElements(file); 268 while (i.hasNext()) 269 fireElementStateChanging(i.next()); 270 } 271 272 275 public void dirtyStateChanged(IFileBuffer file, boolean isDirty) { 276 List list= new ArrayList (fElementStateListeners); 277 Iterator e= list.iterator(); 278 while (e.hasNext()) { 279 IElementStateListener l= (IElementStateListener) e.next(); 280 Iterator i= getElements(file); 281 while (i.hasNext()) 282 l.elementDirtyStateChanged(i.next(), isDirty); 283 } 284 } 285 286 289 public void stateValidationChanged(IFileBuffer file, boolean isStateValidated) { 290 List list= new ArrayList (fElementStateListeners); 291 Iterator e= list.iterator(); 292 while (e.hasNext()) { 293 Object l= e.next(); 294 if (l instanceof IElementStateListenerExtension) { 295 IElementStateListenerExtension x= (IElementStateListenerExtension) l; 296 Iterator i= getElements(file); 297 while (i.hasNext()) 298 x.elementStateValidationChanged(i.next(), isStateValidated); 299 } 300 } 301 } 302 303 306 public void underlyingFileMoved(IFileBuffer file, IPath newLocation) { 307 IWorkspace workspace=ResourcesPlugin.getWorkspace(); 308 IFile newFile= workspace.getRoot().getFile(newLocation); 309 IEditorInput input= newFile == null ? null : new FileEditorInput(newFile); 310 List list= new ArrayList (fElementStateListeners); 311 Iterator e= list.iterator(); 312 while (e.hasNext()) { 313 IElementStateListener l= (IElementStateListener) e.next(); 314 Iterator i= getElements(file); 315 while (i.hasNext()) 316 l.elementMoved(i.next(), input); 317 } 318 } 319 320 323 public void underlyingFileDeleted(IFileBuffer file) { 324 List list= new ArrayList (fElementStateListeners); 325 Iterator e= list.iterator(); 326 while (e.hasNext()) { 327 IElementStateListener l= (IElementStateListener) e.next(); 328 Iterator i= getElements(file); 329 while (i.hasNext()) 330 l.elementDeleted(i.next()); 331 } 332 } 333 334 337 public void stateChangeFailed(IFileBuffer file) { 338 Iterator i= getElements(file); 339 while (i.hasNext()) 340 fireElementStateChangeFailed(i.next()); 341 } 342 343 346 public void bufferCreated(IFileBuffer buffer) { 347 } 349 350 353 public void bufferDisposed(IFileBuffer buffer) { 354 } 356 } 357 358 359 private IDocumentProvider fParentProvider; 360 361 private final Map fFileInfoMap= new HashMap (); 362 363 private final Map fFileBufferMap= new HashMap (); 364 365 private List fElementStateListeners= new ArrayList (); 366 367 private final IFileBufferListener fFileBufferListener= new FileBufferListener(); 368 369 private IProgressMonitor fProgressMonitor; 370 371 private WorkspaceOperationRunner fOperationRunner; 372 373 private IResourceRuleFactory fResourceRuleFactory; 374 375 376 380 public TextFileDocumentProvider() { 381 this(null); 382 } 383 384 390 public TextFileDocumentProvider(IDocumentProvider parentProvider) { 391 IFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 392 manager.setSynchronizationContext(new UISynchronizationContext()); 393 if (parentProvider != null) 394 setParentDocumentProvider(parentProvider); 395 396 fResourceRuleFactory= ResourcesPlugin.getWorkspace().getRuleFactory(); 397 } 398 399 405 final public void setParentDocumentProvider(IDocumentProvider parentProvider) { 406 407 Assert.isTrue(parentProvider instanceof IDocumentProviderExtension); 408 Assert.isTrue(parentProvider instanceof IDocumentProviderExtension2); 409 Assert.isTrue(parentProvider instanceof IDocumentProviderExtension3); 410 Assert.isTrue(parentProvider instanceof IStorageDocumentProvider); 411 412 fParentProvider= parentProvider; 413 } 414 415 420 final protected IDocumentProvider getParentProvider() { 421 if (fParentProvider == null) 422 fParentProvider= new StorageDocumentProvider(); 423 return fParentProvider; 424 } 425 426 432 protected IRunnableContext getOperationRunner(IProgressMonitor monitor) { 433 if (fOperationRunner == null) 434 fOperationRunner = new WorkspaceOperationRunner(); 435 fOperationRunner.setProgressMonitor(monitor); 436 return fOperationRunner; 437 } 438 439 446 protected void executeOperation(DocumentProviderOperation operation, IProgressMonitor monitor) throws CoreException { 447 try { 448 IRunnableContext runner= getOperationRunner(monitor); 449 if (runner != null) 450 runner.run(false, false, operation); 451 else 452 operation.run(monitor); 453 } catch (InvocationTargetException x) { 454 Throwable e= x.getTargetException(); 455 if (e instanceof CoreException) 456 throw (CoreException) e; 457 String message= (e.getMessage() != null ? e.getMessage() : ""); throw new CoreException(new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IStatus.OK, message, e)); 459 } catch (InterruptedException x) { 460 String message= (x.getMessage() != null ? x.getMessage() : ""); throw new CoreException(new Status(IStatus.CANCEL, EditorsUI.PLUGIN_ID, IStatus.OK, message, x)); 462 } 463 } 464 465 468 public void connect(Object element) throws CoreException { 469 FileInfo info= (FileInfo) fFileInfoMap.get(element); 470 if (info == null) { 471 472 info= createFileInfo(element); 473 if (info == null) { 474 getParentProvider().connect(element); 475 return; 476 } 477 478 info.fElement= element; 479 fFileInfoMap.put(element, info); 480 storeFileBufferMapping(element, info); 481 } 482 ++ info.fCount; 483 } 484 485 492 private void storeFileBufferMapping(Object element, FileInfo info) { 493 Object value= fFileBufferMap.get(info.fTextFileBuffer); 494 495 if (value instanceof List ) { 496 List list= (List ) value; 497 list.add(element); 498 return; 499 } 500 501 if (value == null) { 502 value= element; 503 } else { 504 List list= new ArrayList (2); 505 list.add(value); 506 list.add(element); 507 508 value= list; 509 } 510 fFileBufferMap.put(info.fTextFileBuffer, value); 511 } 512 513 522 protected FileInfo createEmptyFileInfo() { 523 return new FileInfo(); 524 } 525 526 539 protected FileInfo createFileInfo(Object element) throws CoreException { 540 if (!(element instanceof IAdaptable)) 541 return null; 542 IAdaptable adaptable= (IAdaptable) element; 543 544 IFile file= null; 545 ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 546 ITextFileBuffer fileBuffer= null; 547 LocationKind locationKind= null; 548 549 file= (IFile)adaptable.getAdapter(IFile.class); 550 if (file != null) { 551 IPath location= file.getFullPath(); 552 locationKind= LocationKind.IFILE; 553 manager.connect(location, locationKind,getProgressMonitor()); 554 fileBuffer= manager.getTextFileBuffer(location, locationKind); 555 } else { 556 ILocationProvider provider= (ILocationProvider) adaptable.getAdapter(ILocationProvider.class); 557 if (provider instanceof ILocationProviderExtension) { 558 URI uri= ((ILocationProviderExtension)provider).getURI(element); 559 if (ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri).length == 0) { 560 IFileStore fileStore= EFS.getStore(uri); 561 manager.connectFileStore(fileStore, getProgressMonitor()); 562 fileBuffer= manager.getFileStoreTextFileBuffer(fileStore); 563 } 564 } 565 if (fileBuffer == null && provider != null) { 566 IPath location= provider.getPath(element); 567 if (location == null) 568 return null; 569 locationKind= LocationKind.NORMALIZE; 570 manager.connect(location, locationKind, getProgressMonitor()); 571 fileBuffer= manager.getTextFileBuffer(location, locationKind); 572 file= FileBuffers.getWorkspaceFileAtLocation(location); 573 } 574 } 575 576 if (fileBuffer != null) { 577 fileBuffer.requestSynchronizationContext(); 578 579 FileInfo info= createEmptyFileInfo(); 580 info.fTextFileBuffer= fileBuffer; 581 info.fTextFileBufferLocationKind= locationKind; 582 info.fCachedReadOnlyState= isSystemFileReadOnly(info); 583 584 if (file != null) 585 info.fModel= createAnnotationModel(file); 586 587 return info; 588 } 589 return null; 590 } 591 592 599 protected void setUpSynchronization(FileInfo info) { 600 if (info == null || info.fTextFileBuffer == null) 601 return; 602 603 IDocument document= info.fTextFileBuffer.getDocument(); 604 IAnnotationModel model= info.fModel; 605 606 if (document instanceof ISynchronizable) { 607 Object lock= ((ISynchronizable)document).getLockObject(); 608 if (lock == null) { 609 lock= new Object (); 610 ((ISynchronizable)document).setLockObject(lock); 611 } 612 if (model instanceof ISynchronizable) 613 ((ISynchronizable) model).setLockObject(lock); 614 } 615 } 616 617 623 protected IAnnotationModel createAnnotationModel(IFile file) { 624 return null; 625 } 626 627 630 public void disconnect(Object element) { 631 FileInfo info= (FileInfo) fFileInfoMap.get(element); 632 633 if (info == null) { 634 getParentProvider().disconnect(element); 635 return; 636 } 637 638 if (info.fCount == 1) { 639 640 fFileInfoMap.remove(element); 641 removeFileBufferMapping(element, info); 642 disposeFileInfo(element, info); 643 644 } else 645 -- info.fCount; 646 } 647 648 655 private void removeFileBufferMapping(Object element, FileInfo info) { 656 Object value= fFileBufferMap.get(info.fTextFileBuffer); 657 if (value == null) 658 return; 659 660 if (value instanceof List ) { 661 List list= (List ) value; 662 list.remove(element); 663 if (list.size() == 1) 664 fFileBufferMap.put(info.fTextFileBuffer, list.get(0)); 665 } else if (value == element) { 666 fFileBufferMap.remove(info.fTextFileBuffer); 667 } 668 } 669 670 680 protected void disposeFileInfo(Object element, FileInfo info) { 681 IFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 682 try { 683 info.fTextFileBuffer.releaseSynchronizationContext(); 684 if (info.fTextFileBufferLocationKind != null) 685 manager.disconnect(info.fTextFileBuffer.getLocation(), info.fTextFileBufferLocationKind, getProgressMonitor()); 686 else 687 manager.disconnectFileStore(info.fTextFileBuffer.getFileStore(), getProgressMonitor()); 688 } catch (CoreException x) { 689 handleCoreException(x, "FileDocumentProvider.disposeElementInfo"); } 691 } 692 693 699 protected Iterator getElements(IFileBuffer file) { 700 Object value= fFileBufferMap.get(file); 701 if (value instanceof List ) 702 return new ArrayList ((List ) value).iterator(); 703 return new SingleElementIterator(value); 704 } 705 706 709 public IDocument getDocument(Object element) { 710 FileInfo info= (FileInfo) fFileInfoMap.get(element); 711 if (info != null) 712 return info.fTextFileBuffer.getDocument(); 713 return getParentProvider().getDocument(element); 714 } 715 716 719 public void resetDocument(Object element) throws CoreException { 720 final FileInfo info= (FileInfo) fFileInfoMap.get(element); 721 if (info != null) { 722 DocumentProviderOperation operation= new DocumentProviderOperation() { 723 726 protected void execute(IProgressMonitor monitor) throws CoreException { 727 info.fTextFileBuffer.revert(monitor); 728 729 if (info.fModel instanceof AbstractMarkerAnnotationModel) { 730 AbstractMarkerAnnotationModel markerModel= (AbstractMarkerAnnotationModel) info.fModel; 731 markerModel.resetMarkers(); 732 } 733 } 734 737 public ISchedulingRule getSchedulingRule() { 738 if (info.fElement instanceof IFileEditorInput) { 739 IFileEditorInput input= (IFileEditorInput) info.fElement; 740 return fResourceRuleFactory.refreshRule((input).getFile()); 741 } 742 return null; 743 } 744 }; 745 executeOperation(operation, getProgressMonitor()); 746 } else { 747 getParentProvider().resetDocument(element); 748 } 749 } 750 751 754 public final void saveDocument(IProgressMonitor monitor, Object element, IDocument document, boolean overwrite) throws CoreException { 755 756 if (element == null) 757 return; 758 759 DocumentProviderOperation operation= createSaveOperation(element, document, overwrite); 760 if (operation != null) 761 executeOperation(operation, monitor); 762 else 763 getParentProvider().saveDocument(monitor, element, document, overwrite); 764 } 765 766 protected DocumentProviderOperation createSaveOperation(final Object element, final IDocument document, final boolean overwrite) throws CoreException { 767 final FileInfo info= (FileInfo) fFileInfoMap.get(element); 768 if (info != null) { 769 770 if (info.fTextFileBuffer.getDocument() != document) { 771 Status status= new Status(IStatus.WARNING, EditorsUI.PLUGIN_ID, IStatus.OK, TextEditorMessages.TextFileDocumentProvider_saveAsTargetOpenInEditor, null); 776 throw new CoreException(status); 777 } 778 779 return new DocumentProviderOperation() { 780 783 public void execute(IProgressMonitor monitor) throws CoreException { 784 commitFileBuffer(monitor, info, overwrite); 785 } 786 789 public ISchedulingRule getSchedulingRule() { 790 if (info.fElement instanceof IFileEditorInput) { 791 IFileEditorInput input= (IFileEditorInput) info.fElement; 792 return computeSchedulingRule(input.getFile()); 793 } 794 return null; 795 } 796 }; 797 798 } else if (element instanceof IFileEditorInput) { 799 800 final IFile file= ((IFileEditorInput) element).getFile(); 801 return new DocumentProviderOperation() { 802 805 public void execute(IProgressMonitor monitor) throws CoreException { 806 createFileFromDocument(monitor, file, document); 807 } 808 811 public ISchedulingRule getSchedulingRule() { 812 return computeSchedulingRule(file); 813 } 814 }; 815 } else if (element instanceof IURIEditorInput) { 816 final URI uri= ((IURIEditorInput)element).getURI(); 817 return new DocumentProviderOperation() { 818 821 public void execute(IProgressMonitor monitor) throws CoreException { 822 createFileStoreFromDocument(monitor, uri, document); 823 } 824 827 public ISchedulingRule getSchedulingRule() { 828 return null; 829 } 830 }; 831 } 832 833 return null; 834 } 835 836 847 protected void commitFileBuffer(IProgressMonitor monitor, FileInfo info, boolean overwrite) throws CoreException { 848 Assert.isNotNull(info); 849 850 852 if (info.fElement instanceof IFileEditorInput) { 853 IFileEditorInput input= (IFileEditorInput) info.fElement; 854 IResource resource= input.getFile(); 855 if (!resource.isSynchronized(IResource.DEPTH_ZERO) && isDeleted(input)) 856 info.fTextFileBuffer.setDirty(true); 857 } 858 859 info.fTextFileBuffer.commit(monitor, overwrite); 860 if (info.fModel instanceof AbstractMarkerAnnotationModel) { 861 AbstractMarkerAnnotationModel model= (AbstractMarkerAnnotationModel) info.fModel; 862 model.updateMarkers(info.fTextFileBuffer.getDocument()); 863 } 864 } 865 866 874 protected void createFileFromDocument(IProgressMonitor monitor, IFile file, IDocument document) throws CoreException { 875 try { 876 monitor.beginTask(TextEditorMessages.TextFileDocumentProvider_beginTask_saving, 2000); 877 ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 878 manager.connect(file.getFullPath(), LocationKind.IFILE, monitor); 879 ITextFileBuffer buffer= ITextFileBufferManager.DEFAULT.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE); 880 buffer.getDocument().set(document.get()); 881 buffer.commit(monitor, true); 882 manager.disconnect(file.getFullPath(), LocationKind.IFILE, monitor); 883 } finally { 884 monitor.done(); 885 } 886 } 887 888 897 private void createFileStoreFromDocument(IProgressMonitor monitor, URI uri, IDocument document) throws CoreException { 898 try { 899 monitor.beginTask(TextEditorMessages.TextFileDocumentProvider_beginTask_saving, 2000); 900 IFileStore fileStore= EFS.getStore(uri); 901 FileBuffers.getTextFileBufferManager().connectFileStore(fileStore, monitor); 902 ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getFileStoreTextFileBuffer(fileStore); 903 buffer.getDocument().set(document.get()); 904 buffer.commit(monitor, true); 905 FileBuffers.getTextFileBufferManager().disconnectFileStore(fileStore, monitor); 906 } finally { 907 monitor.done(); 908 } 909 } 910 911 914 public long getModificationStamp(Object element) { 915 FileInfo info= (FileInfo) fFileInfoMap.get(element); 916 if (info != null) 917 return info.fTextFileBuffer.getModificationStamp(); 918 return getParentProvider().getModificationStamp(element); 919 } 920 921 924 public long getSynchronizationStamp(Object element) { 925 FileInfo info= (FileInfo) fFileInfoMap.get(element); 926 if (info != null) 927 return 0; 928 return getParentProvider().getSynchronizationStamp(element); 929 } 930 931 934 public boolean isDeleted(Object element) { 935 FileInfo info= (FileInfo) fFileInfoMap.get(element); 936 if (info != null) { 937 IFileStore fileStore= getFileStore(info); 938 return fileStore == null ? true : !fileStore.fetchInfo().exists(); 939 } 940 return getParentProvider().isDeleted(element); 941 } 942 943 946 public boolean mustSaveDocument(Object element) { 947 FileInfo info= (FileInfo) fFileInfoMap.get(element); 948 if (info != null) 949 return (info.fCount == 1) && info.fTextFileBuffer.isDirty(); 950 return getParentProvider().mustSaveDocument(element); 951 } 952 953 956 public boolean canSaveDocument(Object element) { 957 FileInfo info= (FileInfo) fFileInfoMap.get(element); 958 if (info != null) 959 return info.fTextFileBuffer.isDirty(); 960 return getParentProvider().canSaveDocument(element); 961 } 962 963 966 public IAnnotationModel getAnnotationModel(Object element) { 967 FileInfo info= (FileInfo) fFileInfoMap.get(element); 968 if (info != null) { 969 if (info.fModel != null) 970 return info.fModel; 971 return info.fTextFileBuffer.getAnnotationModel(); 972 } 973 return getParentProvider().getAnnotationModel(element); 974 } 975 976 979 public void aboutToChange(Object element) { 980 FileInfo info= (FileInfo) fFileInfoMap.get(element); 981 if (info == null) 982 getParentProvider().aboutToChange(element); 983 } 984 985 988 public void changed(Object element) { 989 FileInfo info= (FileInfo) fFileInfoMap.get(element); 990 if (info == null) 991 getParentProvider().changed(element); 992 } 993 994 997 public void addElementStateListener(IElementStateListener listener) { 998 Assert.isNotNull(listener); 999 if (!fElementStateListeners.contains(listener)) { 1000 fElementStateListeners.add(listener); 1001 if (fElementStateListeners.size() == 1) { 1002 IFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 1003 manager.addFileBufferListener(fFileBufferListener); 1004 } 1005 } 1006 getParentProvider().addElementStateListener(listener); 1007 } 1008 1009 1012 public void removeElementStateListener(IElementStateListener listener) { 1013 Assert.isNotNull(listener); 1014 fElementStateListeners.remove(listener); 1015 if (fElementStateListeners.size() == 0) { 1016 IFileBufferManager manager= FileBuffers.getTextFileBufferManager(); 1017 manager.removeFileBufferListener(fFileBufferListener); 1018 } 1019 getParentProvider().removeElementStateListener(listener); 1020 } 1021 1022 1025 public boolean isReadOnly(Object element) { 1026 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1027 if (info != null) 1028 return info.fCachedReadOnlyState; 1029 return ((IDocumentProviderExtension) getParentProvider()).isReadOnly(element); 1030 } 1031 1032 1035 public boolean isModifiable(Object element) { 1036 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1037 if (info != null) 1038 return info.fTextFileBuffer.isStateValidated() ? !isReadOnly(element) : true; 1039 return ((IDocumentProviderExtension) getParentProvider()).isModifiable(element); 1040 } 1041 1042 1045 public void validateState(Object element, final Object computationContext) throws CoreException { 1046 final FileInfo info= (FileInfo) fFileInfoMap.get(element); 1047 if (info != null) { 1048 DocumentProviderOperation operation= new DocumentProviderOperation() { 1049 1052 protected void execute(IProgressMonitor monitor) throws CoreException { 1053 info.fTextFileBuffer.validateState(monitor, computationContext); 1054 } 1055 1058 public ISchedulingRule getSchedulingRule() { 1059 if (info.fElement instanceof IFileEditorInput) { 1060 IFileEditorInput input= (IFileEditorInput) info.fElement; 1061 return fResourceRuleFactory.validateEditRule(new IResource[] { input.getFile() }); 1062 } 1063 return null; 1064 } 1065 }; 1066 executeOperation(operation, getProgressMonitor()); 1067 } else 1068 ((IDocumentProviderExtension) getParentProvider()).validateState(element, computationContext); 1069 } 1070 1071 1074 public boolean isStateValidated(Object element) { 1075 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1076 if (info != null) 1077 return info.fTextFileBuffer.isStateValidated(); 1078 return ((IDocumentProviderExtension) getParentProvider()).isStateValidated(element); 1079 } 1080 1081 1084 public void updateStateCache(Object element) throws CoreException { 1085 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1086 if (info != null) { 1087 boolean isReadOnly= isSystemFileReadOnly(info); 1088 if (!info.fCachedReadOnlyState && isReadOnly ) 1091 info.fTextFileBuffer.resetStateValidation(); 1092 info.fCachedReadOnlyState= isReadOnly; 1093 } else { 1094 ((IDocumentProviderExtension) getParentProvider()).updateStateCache(element); 1095 } 1096 } 1097 1098 1101 public void setCanSaveDocument(Object element) { 1102 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1103 if (info == null) 1104 ((IDocumentProviderExtension) getParentProvider()).setCanSaveDocument(element); 1105 } 1106 1107 1110 public IStatus getStatus(Object element) { 1111 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1112 if (info == null) 1113 return ((IDocumentProviderExtension) getParentProvider()).getStatus(element); 1114 1115 IStatus status= info.fTextFileBuffer.getStatus(); 1116 1117 if (element instanceof IFileEditorInput || element instanceof IURIEditorInput) { 1119 IFileStore fileStore= info.fTextFileBuffer.getFileStore(); 1120 if (fileStore != null && !fileStore.fetchInfo().exists()) { 1121 String message= NLSUtility.format(TextEditorMessages.TextFileDocumentProvider_error_doesNotExist, fileStore.toString()); 1122 return new Status(IStatus.ERROR, EditorsUI.PLUGIN_ID, IResourceStatus.RESOURCE_NOT_FOUND, message, null); 1123 } 1124 } 1125 1126 return status; 1127 } 1128 1129 1132 public void synchronize(Object element) throws CoreException { 1133 final FileInfo info= (FileInfo) fFileInfoMap.get(element); 1134 if (info != null) { 1135 DocumentProviderOperation operation= new DocumentProviderOperation() { 1136 1139 protected void execute(IProgressMonitor monitor) throws CoreException { 1140 info.fTextFileBuffer.revert(monitor); 1141 } 1142 1145 public ISchedulingRule getSchedulingRule() { 1146 if (info.fElement instanceof IFileEditorInput) { 1147 IFileEditorInput input= (IFileEditorInput) info.fElement; 1148 return fResourceRuleFactory.refreshRule(input.getFile()); 1149 } 1150 return null; 1151 } 1152 }; 1153 executeOperation(operation, getProgressMonitor()); 1154 } else { 1155 ((IDocumentProviderExtension) getParentProvider()).synchronize(element); 1156 } 1157 } 1158 1159 1162 public void setProgressMonitor(IProgressMonitor progressMonitor) { 1163 fProgressMonitor= progressMonitor; 1164 ((IDocumentProviderExtension2) getParentProvider()).setProgressMonitor(progressMonitor); 1165 } 1166 1167 1170 public IProgressMonitor getProgressMonitor() { 1171 return fProgressMonitor; 1172 } 1173 1174 1177 public boolean isSynchronized(Object element) { 1178 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1179 if (info != null) 1180 return info.fTextFileBuffer.isSynchronized(); 1181 return ((IDocumentProviderExtension3) getParentProvider()).isSynchronized(element); 1182 } 1183 1184 1188 public boolean isNotSynchronizedException(Object element, CoreException ex) { 1189 IStatus status= ex.getStatus(); 1190 if (status == null || status instanceof MultiStatus) 1191 return false; 1192 1193 if (status.getException() != null) 1194 return false; 1195 1196 return status.getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL; 1197 } 1198 1199 1202 public String getDefaultEncoding() { 1203 return FileBuffers.getTextFileBufferManager().getDefaultEncoding(); 1204 } 1205 1206 1209 public String getEncoding(Object element) { 1210 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1211 if (info != null) 1212 return info.fTextFileBuffer.getEncoding(); 1213 return ((IStorageDocumentProvider) getParentProvider()).getEncoding(element); 1214 } 1215 1216 1219 public void setEncoding(Object element, String encoding) { 1220 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1221 if (info != null) 1222 info.fTextFileBuffer.setEncoding(encoding); 1223 else 1224 ((IStorageDocumentProvider) getParentProvider()).setEncoding(element, encoding); 1225 } 1226 1227 1231 public IContentType getContentType(Object element) throws CoreException { 1232 FileInfo info= (FileInfo) fFileInfoMap.get(element); 1233 if (info != null) 1234 return info.fTextFileBuffer.getContentType(); 1235 IDocumentProvider parent= getParentProvider(); 1236 if (parent instanceof IDocumentProviderExtension4) 1237 return ((IDocumentProviderExtension4) parent).getContentType(element); 1238 return null; 1239 } 1240 1241 1248 protected void handleCoreException(CoreException exception, String message) { 1249 Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID); 1250 ILog log= Platform.getLog(bundle); 1251 IStatus status= message != null ? new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception) : exception.getStatus(); 1252 log.log(status); 1253 } 1254 1255 1262 protected IFileStore getFileStore(FileInfo info) { 1263 return info.fTextFileBuffer.getFileStore(); 1264 } 1265 1266 1273 protected File getSystemFile(FileInfo info) { 1274 IPath path= info.fTextFileBuffer.getLocation(); 1275 return FileBuffers.getSystemFileAtLocation(path); 1276 } 1277 1278 1285 protected boolean isSystemFileReadOnly(FileInfo info) { 1286 IFileStore fileStore= getFileStore(info); 1287 if (fileStore == null) 1288 return false; 1289 IFileInfo fileInfo= fileStore.fetchInfo(); 1290 return fileInfo.exists() && fileInfo.getAttribute(EFS.ATTRIBUTE_READ_ONLY); 1291 } 1292 1293 1299 protected FileInfo getFileInfo(Object element) { 1300 return (FileInfo) fFileInfoMap.get(element); 1301 } 1302 1303 1308 protected Iterator getConnectedElementsIterator() { 1309 return new HashSet (fFileInfoMap.keySet()).iterator(); 1310 } 1311 1312 1317 protected Iterator getFileInfosIterator() { 1318 return new ArrayList (fFileInfoMap.values()).iterator(); 1319 } 1320 1321 1328 protected void fireElementStateChanging(Object element) { 1329 List list= new ArrayList (fElementStateListeners); 1330 Iterator e= list.iterator(); 1331 while (e.hasNext()) { 1332 Object l= e.next(); 1333 if (l instanceof IElementStateListenerExtension) { 1334 IElementStateListenerExtension x= (IElementStateListenerExtension) l; 1335 x.elementStateChanging(element); 1336 } 1337 } 1338 } 1339 1340 1347 protected void fireElementStateChangeFailed(Object element) { 1348 List list= new ArrayList (fElementStateListeners); 1349 Iterator e= list.iterator(); 1350 while (e.hasNext()) { 1351 Object l= e.next(); 1352 if (l instanceof IElementStateListenerExtension) { 1353 IElementStateListenerExtension x= (IElementStateListenerExtension) l; 1354 x.elementStateChangeFailed(element); 1355 } 1356 } 1357 } 1358 1359 1370 protected ISchedulingRule computeSchedulingRule(IResource toCreateOrModify) { 1371 if (toCreateOrModify.exists()) 1372 return fResourceRuleFactory.modifyRule(toCreateOrModify); 1373 1374 IResource parent= toCreateOrModify; 1375 do { 1376 toCreateOrModify= parent; 1377 parent= toCreateOrModify.getParent(); 1378 } while (parent != null && !parent.exists()); 1379 1380 return fResourceRuleFactory.createRule(toCreateOrModify); 1381 } 1382} 1383 | Popular Tags |