1 11 package org.eclipse.ui.internal.texteditor.quickdiff.compare.equivalence; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.Collections ; 16 import java.util.ConcurrentModificationException ; 17 18 import org.eclipse.core.runtime.Assert; 19 20 import org.eclipse.jface.text.BadLocationException; 21 import org.eclipse.jface.text.DocumentEvent; 22 import org.eclipse.jface.text.IDocument; 23 import org.eclipse.jface.text.IRegion; 24 25 28 public final class DocumentEquivalenceClass { 29 30 private static final boolean DEBUG= false; 31 32 private final ArrayList fHashes; 33 private IDocument fDocument; 34 private final IHashFunction fHashFunction; 35 36 public DocumentEquivalenceClass(IDocument document) { 37 this(document, new DJBHashFunction()); 38 } 39 40 public DocumentEquivalenceClass(IDocument document, IHashFunction hashFunction) { 41 fDocument= document; 42 Object [] nulls= new Object [fDocument.getNumberOfLines()]; 43 fHashes= new ArrayList (Arrays.asList(nulls)); 44 45 if (hashFunction == null) 46 throw new NullPointerException ("hashFunction"); fHashFunction= hashFunction; 48 } 49 50 61 public Hash getHash(int line) { 62 try { 63 return internalGetHash(line); 64 } catch (BadLocationException x) { 65 throw new ConcurrentModificationException (); 66 } 67 } 68 69 private Hash internalGetHash(int line) throws BadLocationException { 70 Hash hash= (Hash) fHashes.get(line); 71 if (hash == null) { 72 if (fDocument == null) 73 throw new AssertionError ("hash cannot be null after loadAndForget"); 75 IRegion lineRegion= fDocument.getLineInformation(line); 76 String lineContents= fDocument.get(lineRegion.getOffset(), lineRegion.getLength()); 77 hash= fHashFunction.computeHash(lineContents); 78 fHashes.set(line, hash); 79 } 80 81 return hash; 82 } 83 84 91 public void update(DocumentEvent event) { 92 if (fDocument == null) 93 throw new IllegalStateException ("update must not be called after loadAndForget"); try { 95 internalUpdate(event); 96 } catch (BadLocationException x) { 97 throw new ConcurrentModificationException (); 98 } 99 } 100 101 private void internalUpdate(DocumentEvent event) throws BadLocationException { 102 int linesBefore= fDocument.getNumberOfLines(event.getOffset(), event.getLength()); 103 String text= event.getText(); 104 int linesAfter= (text == null ? 0 : fDocument.computeNumberOfLines(text)) + 1; 105 int firstLine= fDocument.getLineOfOffset(event.getOffset()); 106 107 int delta= linesAfter - linesBefore; 108 int changed= Math.min(linesAfter, linesBefore); 109 110 if (delta > 0) { 111 Object [] nulls= new Object [delta]; 112 fHashes.addAll(firstLine + changed, Arrays.asList(nulls)); 113 } else if (delta < 0) { 114 fHashes.subList(firstLine, firstLine - delta).clear(); 115 } 116 Collections.fill(fHashes.subList(firstLine, firstLine + changed), null); 117 } 118 119 122 public int getCount() { 123 return fHashes.size(); 124 } 125 126 public void setDocument(IDocument document) { 127 Assert.isNotNull(document); 128 if (DEBUG) 129 Assert.isTrue(document.get().equals(fDocument.get())); 130 fDocument= document; 131 } 132 133 137 public void loadAndForget() { 138 int count= getCount(); 139 for (int line= 0; line < count; line++) 140 getHash(line); 141 142 fDocument= null; 143 } 144 } 145 | Popular Tags |