1 33 34 package edu.rice.cs.drjava.model.definitions.reducedmodel; 35 36 import edu.rice.cs.plt.collect.WeakHashSet; 37 import java.util.Set ; 38 39 41 42 48 class ModelList<T> { 49 private Node<T> _head; 50 private Node<T> _tail; 51 52 private int _length; 53 54 private Set<Iterator> _listeners; 55 56 61 ModelList() { 62 _head = new Node<T>(); 66 _tail = new Node<T>(); 67 _head.pred = null; 68 _head.succ = _tail; 69 _tail.pred = _head; 70 _tail.succ = null; 71 _length = 0; 72 78 _listeners = new WeakHashSet<Iterator>(); 79 } 80 81 85 private void insert(Node<T> point, T item) { 86 Node<T> ins = new Node<T>(item, point.pred, point); 87 point.pred.succ = ins; 88 point.pred = ins; 89 _length++; 90 } 91 92 public void insertFront(T item) { 93 Iterator it = new Iterator(); 94 it.insert(item); 95 it.dispose(); 96 } 97 98 102 private void remove(Node<T> point) { 103 if ((point == _head) || (point == _tail)) 104 throw new RuntimeException ("Can't remove head."); 105 else 106 { 107 point.succ.pred = point.pred; 108 point.pred.succ = point.succ; 109 _length--; 110 } 111 } 112 113 private void addListener(Iterator thing) { 114 this._listeners.add(thing); 115 } 116 117 private void removeListener(Iterator thing) { 118 this._listeners.remove(thing); 119 } 120 121 public int listenerCount() { 122 return _listeners.size(); 123 } 124 127 public boolean isEmpty() { 128 return (_head.succ == _tail); 129 } 130 131 public int length() { 132 return _length; 133 } 134 135 140 public Iterator getIterator() { 141 return new Iterator(); 142 } 143 144 145 152 private static class Node<T> { 153 Node<T> pred; 154 Node<T> succ; 155 private T _item; 156 157 Node() { 158 _item = null; 159 pred = this; 160 succ = this; 161 } 162 163 Node(T item, Node<T> previous, Node<T> successor) { 164 _item = item; 165 pred = previous; 166 succ = successor; 167 } 168 169 T getItem() { 170 return _item; 171 } 172 } 173 174 181 class Iterator { 182 private Node<T> _point; 183 private int _pos; 184 185 189 public Iterator() { 190 _point = ModelList.this._head; 191 _pos = 0; 192 ModelList.this.addListener(this); 193 } 194 195 200 public Iterator(Iterator iter) { 201 _point = iter._point; 202 _pos = iter._pos; 203 ModelList.this.addListener(this); 204 } 205 206 public Iterator copy() { 207 return new Iterator(this); 208 } 209 210 213 public boolean eq(Object thing) { 214 return this._point == ((Iterator)(thing))._point; 215 } 216 217 220 public void setTo(Iterator it) { 221 this._point = it._point; 222 this._pos = it._pos; 223 } 224 225 235 public void dispose() { ModelList.this.removeListener(this); } 236 237 238 public boolean atStart() { return (_point == ModelList.this._head); } 239 240 241 public boolean atEnd() { return (_point == ModelList.this._tail); } 242 243 244 public boolean atFirstItem() { return (_point.pred == ModelList.this._head); } 245 246 247 public boolean atLastItem() { return (_point.succ == ModelList.this._tail); } 248 249 250 public T current() { 251 if (atStart()) 252 throw new RuntimeException ("Attempt to call current on an " + 253 "iterator in the initial position"); 254 if (atEnd()) 255 throw new RuntimeException ("Attempt to call current on an " + 256 "iterator in the final position"); 257 return _point.getItem(); 258 } 259 260 263 public T prevItem() { 264 if (atFirstItem() || atStart() || ModelList.this.isEmpty()) 265 throw new RuntimeException ("No more previous items."); 266 return _point.pred.getItem(); 267 } 268 269 272 public T nextItem() { 273 if (atLastItem() || atEnd() || ModelList.this.isEmpty()) 274 throw new RuntimeException ("No more following items."); 275 return _point.succ.getItem(); 276 } 277 278 287 public void insert(T item) { 288 if (this.atStart()) next(); 290 ModelList.this.insert(_point, item); 291 _point = _point.pred; notifyOfInsert(_pos); 293 294 _pos -= 1; 297 } 298 299 304 public void remove() { 305 Node<T> tempNode = _point.succ; 306 ModelList.this.remove(_point); 307 _point = tempNode; 308 notifyOfRemove(_pos, _point); 309 } 310 311 315 public void prev() { 316 if (atStart()) { 317 throw new RuntimeException ("Can't cross list boundary."); 318 } 319 _point = _point.pred; 320 _pos--; 321 } 322 323 327 public void next() { 328 if (atEnd()) throw new RuntimeException ("Can't cross list boundary."); 329 _point = _point.succ; 330 _pos++; 331 } 332 333 345 public void collapse(Iterator iter) { 346 int leftPos; 347 int rightPos; 348 Node<T> rightPoint; 349 350 if (this._pos > iter._pos) { 351 leftPos = iter._pos; 352 rightPos = this._pos; 353 rightPoint = this._point; 354 355 this._point.pred = iter._point; 356 iter._point.succ = this._point; 357 ModelList.this._length -= this._pos - iter._pos - 1; 359 notifyOfCollapse(leftPos, rightPos, rightPoint); 360 } 361 else if (this._pos < iter._pos) { 362 leftPos = this._pos; 363 rightPos = iter._pos; 364 rightPoint = iter._point; 365 366 iter._point.pred = this._point; 367 this._point.succ = iter._point; 368 369 ModelList.this._length -= iter._pos - this._pos - 1; 370 notifyOfCollapse(leftPos, rightPos, rightPoint); 371 } 372 else { } 374 } 375 376 379 private void notifyOfInsert(int pos) { 380 for (Iterator listener : ModelList.this._listeners) { 381 if ( listener._pos < pos ) { 382 } 384 else { listener._pos += 1; 386 } 387 } 388 } 389 390 394 private void notifyOfRemove(int pos, Node<T> point) { 395 for (Iterator listener : ModelList.this._listeners) { 396 if ( listener._pos < pos ) { 397 } 399 else if ( listener._pos == pos ) { 400 listener._point = point; 401 } 402 else { listener._pos -= 1; 404 } 405 } 406 } 407 408 411 private void notifyOfCollapse(int leftPos, int rightPos, Node<T> rightPoint) { 412 for (Iterator listener : ModelList.this._listeners) { 413 if ( listener._pos <= leftPos ) { 414 } 416 else if (( listener._pos > leftPos ) && ( listener._pos <= rightPos )) { 417 listener._pos = leftPos + 1; 418 listener._point = rightPoint; 419 } 420 else { listener._pos -= (rightPos - leftPos - 1); 422 } 423 } 424 } 425 } 426 } 427 | Popular Tags |