1 11 package org.eclipse.jface.text.link; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.LinkedList ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.core.runtime.Assert; 21 22 import org.eclipse.text.edits.MalformedTreeException; 23 import org.eclipse.text.edits.MultiTextEdit; 24 import org.eclipse.text.edits.ReplaceEdit; 25 import org.eclipse.text.edits.TextEdit; 26 27 import org.eclipse.jface.text.BadLocationException; 28 import org.eclipse.jface.text.DocumentEvent; 29 import org.eclipse.jface.text.IDocument; 30 import org.eclipse.jface.text.IRegion; 31 import org.eclipse.jface.text.Position; 32 import org.eclipse.jface.text.Region; 33 34 51 public class LinkedPositionGroup { 52 53 54 public static final int NO_STOP= -1; 55 56 57 58 59 private final List fPositions= new LinkedList (); 60 61 private boolean fIsSealed= false; 62 66 private boolean fHasCustomIteration= false; 67 68 72 73 private LinkedPosition fLastPosition; 74 77 private IRegion fLastRegion; 78 79 100 public void addPosition(LinkedPosition position) throws BadLocationException { 101 105 Assert.isNotNull(position); 106 if (fIsSealed) 107 throw new IllegalStateException ("cannot add positions after the group is added to an model"); 109 if (!fPositions.contains(position)) { 110 enforceDisjoint(position); 111 enforceEqualContent(position); 112 fPositions.add(position); 113 fHasCustomIteration |= position.getSequenceNumber() != LinkedPositionGroup.NO_STOP; 114 } else 115 return; } 117 118 124 private void enforceEqualContent(LinkedPosition position) throws BadLocationException { 125 if (fPositions.size() > 0) { 126 LinkedPosition groupPosition= (LinkedPosition) fPositions.get(0); 127 String groupContent= groupPosition.getContent(); 128 String positionContent= position.getContent(); 129 if (!groupContent.equals(positionContent)) 130 throw new BadLocationException( 131 "First position: '" + groupContent + "' at " + groupPosition.getOffset() + ", this position: '" + positionContent + "' at " + position.getOffset()); } 134 } 135 136 142 private void enforceDisjoint(LinkedPosition position) throws BadLocationException { 143 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 144 LinkedPosition p= (LinkedPosition) it.next(); 145 if (p.overlapsWith(position)) 146 throw new BadLocationException(); 147 } 148 } 149 150 156 void enforceDisjoint(LinkedPositionGroup group) throws BadLocationException { 157 Assert.isNotNull(group); 158 for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) { 159 LinkedPosition p= (LinkedPosition) it.next(); 160 enforceDisjoint(p); 161 } 162 } 163 164 172 boolean isLegalEvent(DocumentEvent event) { 173 fLastPosition= null; 174 fLastRegion= null; 175 176 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 177 LinkedPosition pos= (LinkedPosition) it.next(); 178 if (overlapsOrTouches(pos, event)) { 179 if (fLastPosition != null) { 180 fLastPosition= null; 181 fLastRegion= null; 182 return false; 183 } 184 185 fLastPosition= pos; 186 fLastRegion= new Region(pos.getOffset(), pos.getLength()); 187 } 188 } 189 190 return true; 191 } 192 193 203 private boolean overlapsOrTouches(LinkedPosition position, DocumentEvent event) { 204 return position.getDocument().equals(event.getDocument()) && position.getOffset() <= event.getOffset() + event.getLength() && position.getOffset() + position.getLength() >= event.getOffset(); 205 } 206 207 216 Map handleEvent(DocumentEvent event) { 217 218 if (fLastPosition != null) { 219 220 Map map= new HashMap (); 221 222 223 int relativeOffset= event.getOffset() - fLastRegion.getOffset(); 224 if (relativeOffset < 0) { 225 relativeOffset= 0; 226 } 227 228 int eventEnd= event.getOffset() + event.getLength(); 229 int lastEnd= fLastRegion.getOffset() + fLastRegion.getLength(); 230 int length; 231 if (eventEnd > lastEnd) 232 length= lastEnd - relativeOffset - fLastRegion.getOffset(); 233 else 234 length= eventEnd - relativeOffset - fLastRegion.getOffset(); 235 236 String text= event.getText(); 237 if (text == null) 238 text= ""; 240 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 241 LinkedPosition p= (LinkedPosition) it.next(); 242 if (p == fLastPosition || p.isDeleted()) 243 continue; 245 List edits= (List ) map.get(p.getDocument()); 246 if (edits == null) { 247 edits= new ArrayList (); 248 map.put(p.getDocument(), edits); 249 } 250 251 edits.add(new ReplaceEdit(p.getOffset() + relativeOffset, length, text)); 252 } 253 254 try { 255 for (Iterator it= map.keySet().iterator(); it.hasNext();) { 256 IDocument d= (IDocument) it.next(); 257 TextEdit edit= new MultiTextEdit(0, d.getLength()); 258 edit.addChildren((TextEdit[]) ((List ) map.get(d)).toArray(new TextEdit[0])); 259 map.put(d, edit); 260 } 261 262 return map; 263 } catch (MalformedTreeException x) { 264 return null; 270 } 271 272 } 273 274 return null; 275 } 276 277 281 void seal() { 282 Assert.isTrue(!fIsSealed); 283 fIsSealed= true; 284 285 if (fHasCustomIteration == false && fPositions.size() > 0) { 286 ((LinkedPosition) fPositions.get(0)).setSequenceNumber(0); 287 } 288 } 289 290 IDocument[] getDocuments() { 291 IDocument[] docs= new IDocument[fPositions.size()]; 292 int i= 0; 293 for (Iterator it= fPositions.iterator(); it.hasNext(); i++) { 294 LinkedPosition pos= (LinkedPosition) it.next(); 295 docs[i]= pos.getDocument(); 296 } 297 return docs; 298 } 299 300 void register(LinkedModeModel model) throws BadLocationException { 301 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 302 LinkedPosition pos= (LinkedPosition) it.next(); 303 model.register(pos); 304 } 305 } 306 307 317 LinkedPosition adopt(LinkedPositionGroup group) throws BadLocationException { 318 LinkedPosition found= null; 319 for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) { 320 LinkedPosition pos= (LinkedPosition) it.next(); 321 LinkedPosition localFound= null; 322 for (Iterator it2= fPositions.iterator(); it2.hasNext(); ) { 323 LinkedPosition myPos= (LinkedPosition) it2.next(); 324 if (myPos.includes(pos)) { 325 if (found == null) 326 found= myPos; 327 else if (found != myPos) 328 throw new BadLocationException(); 329 if (localFound == null) 330 localFound= myPos; 331 } 332 } 333 334 if (localFound != found) 335 throw new BadLocationException(); 336 } 337 return found; 338 } 339 340 346 LinkedPosition getPosition(LinkedPosition toFind) { 347 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 348 LinkedPosition p= (LinkedPosition) it.next(); 349 if (p.includes(toFind)) 350 return p; 351 } 352 return null; 353 } 354 355 362 boolean contains(int offset) { 363 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 364 LinkedPosition pos= (LinkedPosition) it.next(); 365 if (pos.includes(offset)) { 366 return true; 367 } 368 } 369 return false; 370 } 371 372 378 public boolean isEmpty() { 379 return fPositions.size() == 0; 380 } 381 382 388 public boolean isEmtpy() { 389 return isEmpty(); 390 } 391 392 399 public LinkedPosition[] getPositions() { 400 return (LinkedPosition[]) fPositions.toArray(new LinkedPosition[0]); 401 } 402 403 409 boolean contains(Position position) { 410 for (Iterator it= fPositions.iterator(); it.hasNext(); ) { 411 LinkedPosition p= (LinkedPosition) it.next(); 412 if (position.equals(p)) 413 return true; 414 } 415 return false; 416 } 417 } 418 | Popular Tags |