1 11 12 package org.eclipse.jface.text; 13 14 15 import java.util.ArrayList ; 16 import java.util.Arrays ; 17 import java.util.HashMap ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.regex.PatternSyntaxException ; 22 23 import org.eclipse.core.runtime.Assert; 24 import org.eclipse.core.runtime.ListenerList; 25 26 27 55 public abstract class AbstractDocument implements IDocument, IDocumentExtension, IDocumentExtension2, IDocumentExtension3, IDocumentExtension4, IRepairableDocument { 56 57 61 private static final boolean DEBUG= false; 62 63 64 70 static private class RegisteredReplace { 71 72 IDocumentListener fOwner; 73 74 IDocumentExtension.IReplace fReplace; 75 76 81 RegisteredReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) { 82 fOwner= owner; 83 fReplace= replace; 84 } 85 } 86 87 88 89 private ITextStore fStore; 90 91 private ILineTracker fTracker; 92 93 private ListenerList fDocumentListeners; 94 95 private ListenerList fPrenotifiedDocumentListeners; 96 97 private ListenerList fDocumentPartitioningListeners; 98 99 private Map fPositions; 100 101 private List fPositionUpdaters; 102 106 private List fPostNotificationChanges; 107 111 private int fReentranceCount= 0; 112 116 private int fStoppedCount= 0; 117 121 private boolean fAcceptPostNotificationReplaces= true; 122 126 private int fStoppedListenerNotification= 0; 127 131 private DocumentEvent fDeferredDocumentEvent; 132 136 private Map fDocumentPartitioners; 137 141 private DocumentPartitioningChangedEvent fDocumentPartitioningChangedEvent; 142 146 private FindReplaceDocumentAdapter fFindReplaceDocumentAdapter; 147 151 private DocumentRewriteSession fDocumentRewriteSession; 152 156 private List fDocumentRewriteSessionListeners; 157 161 private long fModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; 162 166 private long fNextModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP; 167 171 private String fInitialLineDelimiter; 172 173 174 180 protected AbstractDocument() { 181 fModificationStamp= getNextModificationStamp(); 182 } 183 184 185 191 protected ITextStore getStore() { 192 Assert.isNotNull(fStore); 193 return fStore; 194 } 195 196 202 protected ILineTracker getTracker() { 203 Assert.isNotNull(fTracker); 204 return fTracker; 205 } 206 207 212 protected List getDocumentListeners() { 213 return Arrays.asList(fDocumentListeners.getListeners()); 214 } 215 216 221 protected List getDocumentPartitioningListeners() { 222 return Arrays.asList(fDocumentPartitioningListeners.getListeners()); 223 } 224 225 230 protected Map getDocumentManagedPositions() { 231 return fPositions; 232 } 233 234 237 public IDocumentPartitioner getDocumentPartitioner() { 238 return getDocumentPartitioner(DEFAULT_PARTITIONING); 239 } 240 241 242 243 245 251 protected void setTextStore(ITextStore store) { 252 fStore= store; 253 } 254 255 261 protected void setLineTracker(ILineTracker tracker) { 262 fTracker= tracker; 263 } 264 265 268 public void setDocumentPartitioner(IDocumentPartitioner partitioner) { 269 setDocumentPartitioner(DEFAULT_PARTITIONING, partitioner); 270 } 271 272 277 protected void completeInitialization() { 278 279 fPositions= new HashMap (); 280 fPositionUpdaters= new ArrayList (); 281 fDocumentListeners= new ListenerList(); 282 fPrenotifiedDocumentListeners= new ListenerList(); 283 fDocumentPartitioningListeners= new ListenerList(); 284 fDocumentRewriteSessionListeners= new ArrayList (); 285 286 addPositionCategory(DEFAULT_CATEGORY); 287 addPositionUpdater(new DefaultPositionUpdater(DEFAULT_CATEGORY)); 288 } 289 290 291 293 296 public void addDocumentListener(IDocumentListener listener) { 297 Assert.isNotNull(listener); 298 fDocumentListeners.add(listener); 299 } 300 301 304 public void removeDocumentListener(IDocumentListener listener) { 305 Assert.isNotNull(listener); 306 fDocumentListeners.remove(listener); 307 } 308 309 312 public void addPrenotifiedDocumentListener(IDocumentListener listener) { 313 Assert.isNotNull(listener); 314 fPrenotifiedDocumentListeners.add(listener); 315 } 316 317 320 public void removePrenotifiedDocumentListener(IDocumentListener listener) { 321 Assert.isNotNull(listener); 322 fPrenotifiedDocumentListeners.remove(listener); 323 } 324 325 328 public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) { 329 Assert.isNotNull(listener); 330 fDocumentPartitioningListeners.add(listener); 331 } 332 333 336 public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) { 337 Assert.isNotNull(listener); 338 fDocumentPartitioningListeners.remove(listener); 339 } 340 341 344 public void addPosition(String category, Position position) throws BadLocationException, BadPositionCategoryException { 345 346 if ((0 > position.offset) || (0 > position.length) || (position.offset + position.length > getLength())) 347 throw new BadLocationException(); 348 349 if (category == null) 350 throw new BadPositionCategoryException(); 351 352 List list= (List ) fPositions.get(category); 353 if (list == null) 354 throw new BadPositionCategoryException(); 355 356 list.add(computeIndexInPositionList(list, position.offset), position); 357 } 358 359 362 public void addPosition(Position position) throws BadLocationException { 363 try { 364 addPosition(DEFAULT_CATEGORY, position); 365 } catch (BadPositionCategoryException e) { 366 } 367 } 368 369 372 public void addPositionCategory(String category) { 373 374 if (category == null) 375 return; 376 377 if (!containsPositionCategory(category)) 378 fPositions.put(category, new ArrayList ()); 379 } 380 381 384 public void addPositionUpdater(IPositionUpdater updater) { 385 insertPositionUpdater(updater, fPositionUpdaters.size()); 386 } 387 388 391 public boolean containsPosition(String category, int offset, int length) { 392 393 if (category == null) 394 return false; 395 396 List list= (List ) fPositions.get(category); 397 if (list == null) 398 return false; 399 400 int size= list.size(); 401 if (size == 0) 402 return false; 403 404 int index= computeIndexInPositionList(list, offset); 405 if (index < size) { 406 Position p= (Position) list.get(index); 407 while (p != null && p.offset == offset) { 408 if (p.length == length) 409 return true; 410 ++ index; 411 p= (index < size) ? (Position) list.get(index) : null; 412 } 413 } 414 415 return false; 416 } 417 418 421 public boolean containsPositionCategory(String category) { 422 if (category != null) 423 return fPositions.containsKey(category); 424 return false; 425 } 426 427 428 439 protected int computeIndexInPositionList(List positions, int offset) { 440 441 if (positions.size() == 0) 442 return 0; 443 444 int left= 0; 445 int right= positions.size() -1; 446 int mid= 0; 447 Position p= null; 448 449 while (left < right) { 450 451 mid= (left + right) / 2; 452 453 p= (Position) positions.get(mid); 454 if (offset < p.getOffset()) { 455 if (left == mid) 456 right= left; 457 else 458 right= mid -1; 459 } else if (offset > p.getOffset()) { 460 if (right == mid) 461 left= right; 462 else 463 left= mid +1; 464 } else if (offset == p.getOffset()) { 465 left= right= mid; 466 } 467 468 } 469 470 int pos= left; 471 p= (Position) positions.get(pos); 472 if (offset > p.getOffset()) { 473 pos++; 475 } else { 476 do { 478 --pos; 479 if (pos < 0) 480 break; 481 p= (Position) positions.get(pos); 482 } while (offset == p.getOffset()); 483 ++pos; 484 } 485 486 Assert.isTrue(0 <= pos && pos <= positions.size()); 487 488 return pos; 489 } 490 491 494 public int computeIndexInCategory(String category, int offset) throws BadLocationException, BadPositionCategoryException { 495 496 if (0 > offset || offset > getLength()) 497 throw new BadLocationException(); 498 499 List c= (List ) fPositions.get(category); 500 if (c == null) 501 throw new BadPositionCategoryException(); 502 503 return computeIndexInPositionList(c, offset); 504 } 505 506 512 protected void fireDocumentPartitioningChanged() { 513 if (fDocumentPartitioningListeners == null) 514 return; 515 516 Object [] listeners= fDocumentPartitioningListeners.getListeners(); 517 for (int i= 0; i < listeners.length; i++) 518 ((IDocumentPartitioningListener)listeners[i]).documentPartitioningChanged(this); 519 } 520 521 533 protected void fireDocumentPartitioningChanged(IRegion region) { 534 if (fDocumentPartitioningListeners == null) 535 return; 536 537 Object [] listeners= fDocumentPartitioningListeners.getListeners(); 538 for (int i= 0; i < listeners.length; i++) { 539 IDocumentPartitioningListener l= (IDocumentPartitioningListener)listeners[i]; 540 if (l instanceof IDocumentPartitioningListenerExtension) 541 ((IDocumentPartitioningListenerExtension) l).documentPartitioningChanged(this, region); 542 else 543 l.documentPartitioningChanged(this); 544 } 545 } 546 547 556 protected void fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent event) { 557 if (fDocumentPartitioningListeners == null) 558 return; 559 560 Object [] listeners= fDocumentPartitioningListeners.getListeners(); 561 for (int i= 0; i < listeners.length; i++) { 562 IDocumentPartitioningListener l= (IDocumentPartitioningListener)listeners[i]; 563 if (l instanceof IDocumentPartitioningListenerExtension2) { 564 IDocumentPartitioningListenerExtension2 extension2= (IDocumentPartitioningListenerExtension2) l; 565 extension2.documentPartitioningChanged(event); 566 } else if (l instanceof IDocumentPartitioningListenerExtension) { 567 IDocumentPartitioningListenerExtension extension= (IDocumentPartitioningListenerExtension) l; 568 extension.documentPartitioningChanged(this, event.getCoverage()); 569 } else { 570 l.documentPartitioningChanged(this); 571 } 572 } 573 } 574 575 581 protected void fireDocumentAboutToBeChanged(DocumentEvent event) { 582 583 if (fReentranceCount == 0) 585 flushPostNotificationChanges(); 586 587 if (fDocumentPartitioners != null) { 588 Iterator e= fDocumentPartitioners.values().iterator(); 589 while (e.hasNext()) { 590 IDocumentPartitioner p= (IDocumentPartitioner) e.next(); 591 if (p instanceof IDocumentPartitionerExtension3) { 592 IDocumentPartitionerExtension3 extension= (IDocumentPartitionerExtension3) p; 593 if (extension.getActiveRewriteSession() != null) 594 continue; 595 } 596 p.documentAboutToBeChanged(event); 597 } 598 } 599 600 Object [] listeners= fPrenotifiedDocumentListeners.getListeners(); 601 for (int i= 0; i < listeners.length; i++) 602 ((IDocumentListener)listeners[i]).documentAboutToBeChanged(event); 603 604 listeners= fDocumentListeners.getListeners(); 605 for (int i= 0; i < listeners.length; i++) 606 ((IDocumentListener)listeners[i]).documentAboutToBeChanged(event); 607 } 608 609 610 616 protected void updateDocumentStructures(DocumentEvent event) { 617 618 if (fDocumentPartitioners != null) { 619 fDocumentPartitioningChangedEvent= new DocumentPartitioningChangedEvent(this); 620 Iterator e= fDocumentPartitioners.keySet().iterator(); 621 while (e.hasNext()) { 622 String partitioning= (String ) e.next(); 623 IDocumentPartitioner partitioner= (IDocumentPartitioner) fDocumentPartitioners.get(partitioning); 624 625 if (partitioner instanceof IDocumentPartitionerExtension3) { 626 IDocumentPartitionerExtension3 extension= (IDocumentPartitionerExtension3) partitioner; 627 if (extension.getActiveRewriteSession() != null) 628 continue; 629 } 630 631 if (partitioner instanceof IDocumentPartitionerExtension) { 632 IDocumentPartitionerExtension extension= (IDocumentPartitionerExtension) partitioner; 633 IRegion r= extension.documentChanged2(event); 634 if (r != null) 635 fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, r.getOffset(), r.getLength()); 636 } else { 637 if (partitioner.documentChanged(event)) 638 fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, 0, event.getDocument().getLength()); 639 } 640 } 641 } 642 643 if (fPositions.size() > 0) 644 updatePositions(event); 645 } 646 647 655 protected void doFireDocumentChanged(DocumentEvent event) { 656 boolean changed= fDocumentPartitioningChangedEvent != null && !fDocumentPartitioningChangedEvent.isEmpty(); 657 IRegion change= changed ? fDocumentPartitioningChangedEvent.getCoverage() : null; 658 doFireDocumentChanged(event, changed, change); 659 } 660 661 672 protected void doFireDocumentChanged(DocumentEvent event, boolean firePartitionChange, IRegion partitionChange) { 673 doFireDocumentChanged2(event); 674 } 675 676 687 protected void doFireDocumentChanged2(DocumentEvent event) { 688 689 DocumentPartitioningChangedEvent p= fDocumentPartitioningChangedEvent; 690 fDocumentPartitioningChangedEvent= null; 691 if (p != null && !p.isEmpty()) 692 fireDocumentPartitioningChanged(p); 693 694 Object [] listeners= fPrenotifiedDocumentListeners.getListeners(); 695 for (int i= 0; i < listeners.length; i++) 696 ((IDocumentListener)listeners[i]).documentChanged(event); 697 698 listeners= fDocumentListeners.getListeners(); 699 for (int i= 0; i < listeners.length; i++) 700 ((IDocumentListener)listeners[i]).documentChanged(event); 701 702 ++ fReentranceCount; 704 try { 705 if (fReentranceCount == 1) 706 executePostNotificationChanges(); 707 } finally { 708 -- fReentranceCount; 709 } 710 } 711 712 719 protected void fireDocumentChanged(DocumentEvent event) { 720 updateDocumentStructures(event); 721 722 if (fStoppedListenerNotification == 0) 723 doFireDocumentChanged(event); 724 else 725 fDeferredDocumentEvent= event; 726 } 727 728 731 public char getChar(int pos) throws BadLocationException { 732 if ((0 > pos) || (pos >= getLength())) 733 throw new BadLocationException(); 734 return getStore().get(pos); 735 } 736 737 740 public String getContentType(int offset) throws BadLocationException { 741 String contentType= null; 742 try { 743 contentType= getContentType(DEFAULT_PARTITIONING, offset, false); 744 Assert.isNotNull(contentType); 745 } catch (BadPartitioningException e) { 746 Assert.isTrue(false); 747 } 748 return contentType; 749 } 750 751 754 public String [] getLegalContentTypes() { 755 String [] contentTypes= null; 756 try { 757 contentTypes= getLegalContentTypes(DEFAULT_PARTITIONING); 758 Assert.isNotNull(contentTypes); 759 } catch (BadPartitioningException e) { 760 Assert.isTrue(false); 761 } 762 return contentTypes; 763 } 764 765 768 public int getLength() { 769 return getStore().getLength(); 770 } 771 772 775 public String getLineDelimiter(int line) throws BadLocationException { 776 return getTracker().getLineDelimiter(line); 777 } 778 779 782 public String [] getLegalLineDelimiters() { 783 return getTracker().getLegalLineDelimiters(); 784 } 785 786 790 public String getDefaultLineDelimiter() { 791 792 String lineDelimiter= null; 793 794 try { 795 lineDelimiter= getLineDelimiter(0); 796 } catch (BadLocationException x) { 797 } 798 799 if (lineDelimiter != null) 800 return lineDelimiter; 801 802 if (fInitialLineDelimiter != null) 803 return fInitialLineDelimiter; 804 805 String sysLineDelimiter= System.getProperty("line.separator"); String [] delimiters= getLegalLineDelimiters(); 807 Assert.isTrue(delimiters.length > 0); 808 for (int i= 0; i < delimiters.length; i++) { 809 if (delimiters[i].equals(sysLineDelimiter)) { 810 lineDelimiter= sysLineDelimiter; 811 break; 812 } 813 } 814 815 if (lineDelimiter == null) 816 lineDelimiter= delimiters[0]; 817 818 return lineDelimiter; 819 820 } 821 822 826 public void setInitialLineDelimiter(String lineDelimiter) { 827 Assert.isNotNull(lineDelimiter); 828 fInitialLineDelimiter= lineDelimiter; 829 } 830 831 834 public int getLineLength(int line) throws BadLocationException { 835 return getTracker().getLineLength(line); 836 } 837 838 841 public int getLineOfOffset(int pos) throws BadLocationException { 842 return getTracker().getLineNumberOfOffset(pos); 843 } 844 845 848 public int getLineOffset(int line) throws BadLocationException { 849 return getTracker().getLineOffset(line); 850 } 851 852 855 public IRegion getLineInformation(int line) throws BadLocationException { 856 return getTracker().getLineInformation(line); 857 } 858 859 862 public IRegion getLineInformationOfOffset(int offset) throws BadLocationException { 863 return getTracker().getLineInformationOfOffset(offset); 864 } 865 866 869 public int getNumberOfLines() { 870 return getTracker().getNumberOfLines(); 871 } 872 873 876 public int getNumberOfLines(int offset, int length) throws BadLocationException { 877 return getTracker().getNumberOfLines(offset, length); 878 } 879 880 883 public int computeNumberOfLines(String text) { 884 return getTracker().computeNumberOfLines(text); 885 } 886 887 890 public ITypedRegion getPartition(int offset) throws BadLocationException { 891 ITypedRegion partition= null; 892 try { 893 partition= getPartition(DEFAULT_PARTITIONING, offset, false); 894 Assert.isNotNull(partition); 895 } catch (BadPartitioningException e) { 896 Assert.isTrue(false); 897 } 898 return partition; 899 } 900 901 904 public ITypedRegion[] computePartitioning(int offset, int length) throws BadLocationException { 905 ITypedRegion[] partitioning= null; 906 try { 907 partitioning= computePartitioning(DEFAULT_PARTITIONING, offset, length, false); 908 Assert.isNotNull(partitioning); 909 } catch (BadPartitioningException e) { 910 Assert.isTrue(false); 911 } 912 return partitioning; 913 } 914 915 918 public Position[] getPositions(String category) throws BadPositionCategoryException { 919 920 if (category == null) 921 throw new BadPositionCategoryException(); 922 923 List c= (List ) fPositions.get(category); 924 if (c == null) 925 throw new BadPositionCategoryException(); 926 927 Position[] positions= new Position[c.size()]; 928 c.toArray(positions); 929 return positions; 930 } 931 932 935 public String [] getPositionCategories() { 936 String [] categories= new String [fPositions.size()]; 937 Iterator keys= fPositions.keySet().iterator(); 938 for (int i= 0; i < categories.length; i++) 939 categories[i]= (String ) keys.next(); 940 return categories; 941 } 942 943 946 public IPositionUpdater[] getPositionUpdaters() { 947 IPositionUpdater[] updaters= new IPositionUpdater[fPositionUpdaters.size()]; 948 fPositionUpdaters.toArray(updaters); 949 return updaters; 950 } 951 952 955 public String get() { 956 return getStore().get(0, getLength()); 957 } 958 959 962 public String get(int pos, int length) throws BadLocationException { 963 int myLength= getLength(); 964 if ((0 > pos) || (0 > length) || (pos + length > myLength)) 965 throw new BadLocationException(); 966 return getStore().get(pos, length); 967 } 968 969 972 public void insertPositionUpdater(IPositionUpdater updater, int index) { 973 974 for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) { 975 if (fPositionUpdaters.get(i) == updater) 976 return; 977 } 978 979 if (index == fPositionUpdaters.size()) 980 fPositionUpdaters.add(updater); 981 else 982 fPositionUpdaters.add(index, updater); 983 } 984 985 988 public void removePosition(String category, Position position) throws BadPositionCategoryException { 989 990 if (position == null) 991 return; 992 993 if (category == null) 994 throw new BadPositionCategoryException(); 995 996 List c= (List ) fPositions.get(category); 997 if (c == null) 998 throw new BadPositionCategoryException(); 999 1000 int size= c.size(); 1002 for (int i= 0; i < size; i++) { 1003 if (position == c.get(i)) { 1004 c.remove(i); 1005 return; 1006 } 1007 } 1008 } 1009 1010 1013 public void removePosition(Position position) { 1014 try { 1015 removePosition(DEFAULT_CATEGORY, position); 1016 } catch (BadPositionCategoryException e) { 1017 } 1018 } 1019 1020 1023 public void removePositionCategory(String category) throws BadPositionCategoryException { 1024 1025 if (category == null) 1026 return; 1027 1028 if ( !containsPositionCategory(category)) 1029 throw new BadPositionCategoryException(); 1030 1031 fPositions.remove(category); 1032 } 1033 1034 1037 public void removePositionUpdater(IPositionUpdater updater) { 1038 for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) { 1039 if (fPositionUpdaters.get(i) == updater) { 1040 fPositionUpdaters.remove(i); 1041 return; 1042 } 1043 } 1044 } 1045 1046 private long getNextModificationStamp() { 1047 if (fNextModificationStamp == Long.MAX_VALUE || fNextModificationStamp == IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) 1048 fNextModificationStamp= 0; 1049 else 1050 fNextModificationStamp= fNextModificationStamp + 1; 1051 1052 return fNextModificationStamp; 1053 } 1054 1055 1059 public long getModificationStamp() { 1060 return fModificationStamp; 1061 } 1062 1063 1067 public void replace(int pos, int length, String text, long modificationStamp) throws BadLocationException { 1068 if ((0 > pos) || (0 > length) || (pos + length > getLength())) 1069 throw new BadLocationException(); 1070 1071 DocumentEvent e= new DocumentEvent(this, pos, length, text); 1072 fireDocumentAboutToBeChanged(e); 1073 1074 getStore().replace(pos, length, text); 1075 getTracker().replace(pos, length, text); 1076 1077 fModificationStamp= modificationStamp; 1078 fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp); 1079 e.fModificationStamp= fModificationStamp; 1080 1081 fireDocumentChanged(e); 1082 } 1083 1084 1087 public void replace(int pos, int length, String text) throws BadLocationException { 1088 if (length == 0 && (text == null || text.length() == 0)) 1089 replace(pos, length, text, getModificationStamp()); 1090 else 1091 replace(pos, length, text, getNextModificationStamp()); 1092 } 1093 1094 1097 public void set(String text) { 1098 set(text, getNextModificationStamp()); 1099 } 1100 1101 1104 public void set(String text, long modificationStamp) { 1105 int length= getStore().getLength(); 1106 1107 DocumentEvent e= new DocumentEvent(this, 0, length, text); 1108 fireDocumentAboutToBeChanged(e); 1109 1110 getStore().set(text); 1111 getTracker().set(text); 1112 1113 fModificationStamp= modificationStamp; 1114 fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp); 1115 e.fModificationStamp= fModificationStamp; 1116 1117 fireDocumentChanged(e); 1118 } 1119 1120 1128 protected void updatePositions(DocumentEvent event) { 1129 List list= new ArrayList (fPositionUpdaters); 1130 Iterator e= list.iterator(); 1131 while (e.hasNext()) { 1132 IPositionUpdater u= (IPositionUpdater) e.next(); 1133 u.update(event); 1134 } 1135 } 1136 1137 1140 public int search(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean wholeWord) throws BadLocationException { 1141 try { 1142 IRegion region= getFindReplaceDocumentAdapter().find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false); 1143 return region == null ? -1 : region.getOffset(); 1144 } catch (IllegalStateException ex) { 1145 return -1; 1146 } catch (PatternSyntaxException ex) { 1147 return -1; 1148 } 1149 } 1150 1151 1157 private FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() { 1158 if (fFindReplaceDocumentAdapter == null) 1159 fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(this); 1160 1161 return fFindReplaceDocumentAdapter; 1162 } 1163 1164 1169 private void flushPostNotificationChanges() { 1170 if (fPostNotificationChanges != null) 1171 fPostNotificationChanges.clear(); 1172 } 1173 1174 1180 private void executePostNotificationChanges() { 1181 1182 if (fStoppedCount > 0) 1183 return; 1184 1185 while (fPostNotificationChanges != null) { 1186 List changes= fPostNotificationChanges; 1187 fPostNotificationChanges= null; 1188 1189 Iterator e= changes.iterator(); 1190 while (e.hasNext()) { 1191 RegisteredReplace replace= (RegisteredReplace) e.next(); 1192 replace.fReplace.perform(this, replace.fOwner); 1193 } 1194 } 1195 } 1196 1197 1201 public void acceptPostNotificationReplaces() { 1202 fAcceptPostNotificationReplaces= true; 1203 } 1204 1205 1209 public void ignorePostNotificationReplaces() { 1210 fAcceptPostNotificationReplaces= false; 1211 } 1212 1213 1217 public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) { 1218 if (fAcceptPostNotificationReplaces) { 1219 if (fPostNotificationChanges == null) 1220 fPostNotificationChanges= new ArrayList (1); 1221 fPostNotificationChanges.add(new RegisteredReplace(owner, replace)); 1222 } 1223 } 1224 1225 1229 public void stopPostNotificationProcessing() { 1230 ++ fStoppedCount; 1231 } 1232 1233 1237 public void resumePostNotificationProcessing() { 1238 -- fStoppedCount; 1239 if (fStoppedCount == 0 && fReentranceCount == 0) 1240 executePostNotificationChanges(); 1241 } 1242 1243 1247 public void startSequentialRewrite(boolean normalized) { 1248 } 1249 1250 1254 public void stopSequentialRewrite() { 1255 } 1256 1257 1261 public void resumeListenerNotification() { 1262 -- fStoppedListenerNotification; 1263 if (fStoppedListenerNotification == 0) { 1264 resumeDocumentListenerNotification(); 1265 } 1266 } 1267 1268 1272 public void stopListenerNotification() { 1273 ++ fStoppedListenerNotification; 1274 } 1275 1276 1282 private void resumeDocumentListenerNotification() { 1283 if (fDeferredDocumentEvent != null) { 1284 DocumentEvent event= fDeferredDocumentEvent; 1285 fDeferredDocumentEvent= null; 1286 doFireDocumentChanged(event); 1287 } 1288 } 1289 1290 1294 public ITypedRegion[] computePartitioning(String partitioning, int offset, int length, boolean includeZeroLengthPartitions) throws BadLocationException, BadPartitioningException { 1295 if ((0 > offset) || (0 > length) || (offset + length > getLength())) 1296 throw new BadLocationException(); 1297 1298 IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); 1299 1300 if (partitioner instanceof IDocumentPartitionerExtension2) { 1301 checkStateOfPartitioner(partitioner, partitioning); 1302 return ((IDocumentPartitionerExtension2) partitioner).computePartitioning(offset, length, includeZeroLengthPartitions); 1303 } else if (partitioner != null) { 1304 checkStateOfPartitioner(partitioner, partitioning); 1305 return partitioner.computePartitioning(offset, length); 1306 } else if (DEFAULT_PARTITIONING.equals(partitioning)) 1307 return new TypedRegion[] { new TypedRegion(offset, length, DEFAULT_CONTENT_TYPE) }; 1308 else 1309 throw new BadPartitioningException(); 1310 } 1311 1312 1316 public String getContentType(String partitioning, int offset, boolean preferOpenPartitions) throws BadLocationException, BadPartitioningException { 1317 if ((0 > offset) || (offset > getLength())) 1318 throw new BadLocationException(); 1319 1320 IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); 1321 1322 if (partitioner instanceof IDocumentPartitionerExtension2) { 1323 checkStateOfPartitioner(partitioner, partitioning); 1324 return ((IDocumentPartitionerExtension2) partitioner).getContentType(offset, preferOpenPartitions); 1325 } else if (partitioner != null) { 1326 checkStateOfPartitioner(partitioner, partitioning); 1327 return partitioner.getContentType(offset); 1328 } else if (DEFAULT_PARTITIONING.equals(partitioning)) 1329 return DEFAULT_CONTENT_TYPE; 1330 else 1331 throw new BadPartitioningException(); 1332 } 1333 1334 1338 public IDocumentPartitioner getDocumentPartitioner(String partitioning) { 1339 return fDocumentPartitioners != null ? (IDocumentPartitioner) fDocumentPartitioners.get(partitioning) : null; 1340 } 1341 1342 1346 public String [] getLegalContentTypes(String partitioning) throws BadPartitioningException { 1347 IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); 1348 if (partitioner != null) 1349 return partitioner.getLegalContentTypes(); 1350 if (DEFAULT_PARTITIONING.equals(partitioning)) 1351 return new String [] { DEFAULT_CONTENT_TYPE }; 1352 throw new BadPartitioningException(); 1353 } 1354 1355 1359 public ITypedRegion getPartition(String partitioning, int offset, boolean preferOpenPartitions) throws BadLocationException, BadPartitioningException { 1360 if ((0 > offset) || (offset > getLength())) 1361 throw new BadLocationException(); 1362 1363 IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning); 1364 1365 if (partitioner instanceof IDocumentPartitionerExtension2) { 1366 checkStateOfPartitioner(partitioner, partitioning); 1367 return ((IDocumentPartitionerExtension2) partitioner).getPartition(offset, preferOpenPartitions); 1368 } else if (partitioner != null) { 1369 checkStateOfPartitioner(partitioner, partitioning); 1370 return partitioner.getPartition(offset); 1371 } else if (DEFAULT_PARTITIONING.equals(partitioning)) 1372 return new TypedRegion(0, getLength(), DEFAULT_CONTENT_TYPE); 1373 else 1374 throw new BadPartitioningException(); 1375 } 1376 1377 1381 public String [] getPartitionings() { 1382 if (fDocumentPartitioners == null) 1383 return new String [0]; 1384 String [] partitionings= new String [fDocumentPartitioners.size()]; 1385 fDocumentPartitioners.keySet().toArray(partitionings); 1386 return partitionings; 1387 } 1388 1389 1393 public void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner) { 1394 if (partitioner == null) { 1395 if (fDocumentPartitioners != null) { 1396 fDocumentPartitioners.remove(partitioning); 1397 if (fDocumentPartitioners.size() == 0) 1398 fDocumentPartitioners= null; 1399 } 1400 } else { 1401 if (fDocumentPartitioners == null) 1402 fDocumentPartitioners= new HashMap (); 1403 fDocumentPartitioners.put(partitioning, partitioner); 1404 } 1405 DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); 1406 event.setPartitionChange(partitioning, 0, getLength()); 1407 fireDocumentPartitioningChanged(event); 1408 } 1409 1410 1414 public void repairLineInformation() { 1415 getTracker().set(get()); 1416 } 1417 1418 1424 protected void fireRewriteSessionChanged(DocumentRewriteSessionEvent event) { 1425 if (fDocumentRewriteSessionListeners.size() > 0) { 1426 List list= new ArrayList (fDocumentRewriteSessionListeners); 1427 Iterator e= list.iterator(); 1428 while (e.hasNext()) { 1429 IDocumentRewriteSessionListener l= (IDocumentRewriteSessionListener) e.next(); 1430 l.documentRewriteSessionChanged(event); 1431 } 1432 } 1433 } 1434 1435 1438 public final DocumentRewriteSession getActiveRewriteSession() { 1439 return fDocumentRewriteSession; 1440 } 1441 1442 1446 public DocumentRewriteSession startRewriteSession(DocumentRewriteSessionType sessionType) { 1447 1448 if (getActiveRewriteSession() != null) 1449 throw new IllegalStateException (); 1450 1451 1452 fDocumentRewriteSession= new DocumentRewriteSession(sessionType); 1453 if (DEBUG) 1454 System.out.println("AbstractDocument: Starting rewrite session: " + fDocumentRewriteSession); 1456 fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, fDocumentRewriteSession, DocumentRewriteSessionEvent.SESSION_START)); 1457 1458 startRewriteSessionOnPartitioners(fDocumentRewriteSession); 1459 1460 ILineTracker tracker= getTracker(); 1461 if (tracker instanceof ILineTrackerExtension) { 1462 ILineTrackerExtension extension= (ILineTrackerExtension) tracker; 1463 extension.startRewriteSession(fDocumentRewriteSession); 1464 } 1465 1466 if (DocumentRewriteSessionType.SEQUENTIAL == sessionType) 1467 startSequentialRewrite(false); 1468 else if (DocumentRewriteSessionType.STRICTLY_SEQUENTIAL == sessionType) 1469 startSequentialRewrite(true); 1470 1471 return fDocumentRewriteSession; 1472 } 1473 1474 1480 protected final void startRewriteSessionOnPartitioners(DocumentRewriteSession session) { 1481 if (fDocumentPartitioners != null) { 1482 Iterator e= fDocumentPartitioners.values().iterator(); 1483 while (e.hasNext()) { 1484 Object partitioner= e.next(); 1485 if (partitioner instanceof IDocumentPartitionerExtension3) { 1486 IDocumentPartitionerExtension3 extension= (IDocumentPartitionerExtension3) partitioner; 1487 extension.startRewriteSession(session); 1488 } 1489 } 1490 } 1491 } 1492 1493 1497 public void stopRewriteSession(DocumentRewriteSession session) { 1498 if (fDocumentRewriteSession == session) { 1499 1500 if (DEBUG) 1501 System.out.println("AbstractDocument: Stopping rewrite session: " + session); 1503 DocumentRewriteSessionType sessionType= session.getSessionType(); 1504 if (DocumentRewriteSessionType.SEQUENTIAL == sessionType || DocumentRewriteSessionType.STRICTLY_SEQUENTIAL == sessionType) 1505 stopSequentialRewrite(); 1506 1507 ILineTracker tracker= getTracker(); 1508 if (tracker instanceof ILineTrackerExtension) { 1509 ILineTrackerExtension extension= (ILineTrackerExtension) tracker; 1510 extension.stopRewriteSession(session, get()); 1511 } 1512 1513 stopRewriteSessionOnPartitioners(fDocumentRewriteSession); 1514 1515 fDocumentRewriteSession= null; 1516 fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, session, DocumentRewriteSessionEvent.SESSION_STOP)); 1517 } 1518 } 1519 1520 1526 protected final void stopRewriteSessionOnPartitioners(DocumentRewriteSession session) { 1527 if (fDocumentPartitioners != null) { 1528 DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); 1529 Iterator e= fDocumentPartitioners.keySet().iterator(); 1530 while (e.hasNext()) { 1531 String partitioning= (String ) e.next(); 1532 IDocumentPartitioner partitioner= (IDocumentPartitioner) fDocumentPartitioners.get(partitioning); 1533 if (partitioner instanceof IDocumentPartitionerExtension3) { 1534 IDocumentPartitionerExtension3 extension= (IDocumentPartitionerExtension3) partitioner; 1535 extension.stopRewriteSession(session); 1536 event.setPartitionChange(partitioning, 0, getLength()); 1537 } 1538 } 1539 if (!event.isEmpty()) 1540 fireDocumentPartitioningChanged(event); 1541 } 1542 } 1543 1544 1548 public void addDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) { 1549 Assert.isNotNull(listener); 1550 if (! fDocumentRewriteSessionListeners.contains(listener)) 1551 fDocumentRewriteSessionListeners.add(listener); 1552 } 1553 1554 1558 public void removeDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) { 1559 Assert.isNotNull(listener); 1560 fDocumentRewriteSessionListeners.remove(listener); 1561 } 1562 1563 1571 protected final void checkStateOfPartitioner(IDocumentPartitioner partitioner, String partitioning) { 1572 if (!(partitioner instanceof IDocumentPartitionerExtension3)) 1573 return; 1574 1575 IDocumentPartitionerExtension3 extension= (IDocumentPartitionerExtension3) partitioner; 1576 DocumentRewriteSession session= extension.getActiveRewriteSession(); 1577 if (session != null) { 1578 extension.stopRewriteSession(session); 1579 1580 if (DEBUG) 1581 System.out.println("AbstractDocument: Flushing rewrite session for partition type: " + partitioning); 1583 DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this); 1584 event.setPartitionChange(partitioning, 0, getLength()); 1585 fireDocumentPartitioningChanged(event); 1586 } 1587 } 1588} 1589 | Popular Tags |