~ubuntu-branches/ubuntu/precise/classpath/precise

« back to all changes in this revision

Viewing changes to javax/swing/text/GapContent.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2006-05-27 16:11:15 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20060527161115-h6e39eposdt5snb6
Tags: 2:0.91-3
* Install header files to /usr/include/classpath.
* debian/control: classpath: Conflict with jamvm < 1.4.3 and
  cacao < 0.96 (Closes: #368172).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* GapContent.java --
2
 
   Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
 
2
   Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
3
3
 
4
4
This file is part of GNU Classpath.
5
5
 
39
39
package javax.swing.text;
40
40
 
41
41
import java.io.Serializable;
 
42
import java.lang.ref.WeakReference;
42
43
import java.util.ArrayList;
43
44
import java.util.Collections;
 
45
import java.util.Comparator;
44
46
import java.util.Iterator;
45
47
import java.util.ListIterator;
46
48
import java.util.Vector;
64
66
public class GapContent
65
67
    implements AbstractDocument.Content, Serializable
66
68
{
 
69
  
67
70
  /**
68
71
   * A {@link Position} implementation for <code>GapContent</code>.
69
72
   */
70
 
  class GapContentPosition
71
 
      implements Position, Comparable
 
73
  private class GapContentPosition
 
74
    implements Position, Comparable
72
75
  {
73
76
 
74
77
    /** The index within the buffer array. */
100
103
    public int compareTo(Object o)
101
104
    {
102
105
      if (o instanceof Integer)
103
 
      {
104
 
        int otherMark = ((Integer) o).intValue();
105
 
        return mark - otherMark;
106
 
      }
 
106
        {
 
107
          int otherMark = ((Integer) o).intValue();
 
108
          return mark - otherMark;
 
109
        }
107
110
      else
108
 
      {
109
 
        GapContentPosition other = (GapContentPosition) o;
110
 
        return mark - other.mark;
111
 
      }
 
111
        {
 
112
          GapContentPosition other = (GapContentPosition) o;
 
113
          return mark - other.mark;
 
114
        }
112
115
    }
113
116
 
114
117
    /**
122
125
      assert mark <= gapStart || mark >= gapEnd : "mark: " + mark
123
126
                                               + ", gapStart: " + gapStart
124
127
                                               + ", gapEnd: " + gapEnd;
125
 
 
126
128
      if (mark <= gapStart)
127
129
        return mark;
128
130
      else
130
132
    }
131
133
  }
132
134
 
133
 
  class UndoInsertString extends AbstractUndoableEdit
 
135
  private class InsertUndo extends AbstractUndoableEdit
134
136
  {
135
137
    public int where, length;
136
138
    String text;
137
 
    public UndoInsertString(int start, int len)
 
139
    public InsertUndo(int start, int len)
138
140
    {
139
141
      where = start;
140
142
      length = len;
169
171
    
170
172
  }
171
173
  
172
 
  class UndoRemove extends AbstractUndoableEdit
 
174
  private class UndoRemove extends AbstractUndoableEdit
173
175
  {
174
176
    public int where;
175
177
    String text;
206
208
    }
207
209
    
208
210
  }
209
 
  
 
211
 
 
212
  /**
 
213
   * Compares WeakReference objects in a List by comparing the referenced
 
214
   * objects instead.
 
215
   *
 
216
   * @author Roman Kennke (kennke@aicas.com)
 
217
   */
 
218
  private class WeakPositionComparator
 
219
    implements Comparator
 
220
  {
 
221
 
 
222
    /**
 
223
     * Compares two objects of type WeakReference. The objects are compared
 
224
     * using the referenced objects compareTo() method.
 
225
     */
 
226
    public int compare(Object o1, Object o2)
 
227
    {
 
228
      // Unwrap references.
 
229
      if (o1 instanceof WeakReference)
 
230
        o1 = ((WeakReference) o1).get();
 
231
      if (o2 instanceof WeakReference)
 
232
        o2 = ((WeakReference) o2).get();
 
233
 
 
234
      GapContentPosition p1 = (GapContentPosition) o1;
 
235
      GapContentPosition p2 = (GapContentPosition) o2;
 
236
 
 
237
      int retVal;
 
238
      if (p1 == null || p2 == null)
 
239
        retVal = -1;
 
240
      else
 
241
        retVal = p1.compareTo(p2);
 
242
      return retVal;
 
243
    }
 
244
  }
 
245
 
210
246
  /** The serialization UID (compatible with JDK1.5). */
211
247
  private static final long serialVersionUID = -6226052713477823730L;
212
248
 
233
269
 
234
270
  /**
235
271
   * The positions generated by this GapContent. They are kept in an ordered
236
 
   * fashion, so they can be looked up easily.
 
272
   * fashion, so they can be looked up easily. The value objects will be
 
273
   * WeakReference objects that in turn hold GapContentPosition objects.
237
274
   */
238
 
  ArrayList positions;
 
275
  private ArrayList positions;
239
276
 
240
277
  /**
241
278
   * Creates a new GapContent object.
252
289
   */
253
290
  public GapContent(int size)
254
291
  {
 
292
    size = Math.max(size, 2);
255
293
    buffer = (char[]) allocateArray(size);
256
294
    gapStart = 1;
257
295
    gapEnd = size;
310
348
    int length = length();
311
349
    int strLen = str.length();
312
350
 
313
 
    if (where >= length)
314
 
      throw new BadLocationException("the where argument cannot be greater"
 
351
    if (where < 0)
 
352
      throw new BadLocationException("The where argument cannot be smaller"
 
353
                                     + " than the zero", where);
 
354
 
 
355
    if (where > length)
 
356
      throw new BadLocationException("The where argument cannot be greater"
315
357
          + " than the content length", where);
316
358
 
317
359
    replace(where, 0, str.toCharArray(), strLen);
318
360
 
319
 
    return new UndoInsertString(where, strLen);
 
361
    return new InsertUndo(where, strLen);
320
362
  }
321
363
 
322
364
  /**
334
376
  {
335
377
    // check arguments
336
378
    int length = length();
337
 
 
338
 
    if (where >= length)
339
 
      throw new BadLocationException("the where argument cannot be greater"
340
 
          + " than the content length", where);
341
 
    if ((where + nitems) > length)
 
379
    
 
380
    if ((where + nitems) >= length)
342
381
      throw new BadLocationException("where + nitems cannot be greater"
343
382
          + " than the content length", where + nitems);
344
 
 
 
383
    
345
384
    String removedText = getString(where, nitems);
346
385
    replace(where, nitems, null, 0);
347
386
 
398
437
  {
399
438
    // check arguments
400
439
    int length = length();
 
440
    if (where < 0)
 
441
      throw new BadLocationException("the where argument may not be below zero", where);
401
442
    if (where >= length)
402
443
      throw new BadLocationException("the where argument cannot be greater"
403
444
          + " than the content length", where);
446
487
      throw new BadLocationException("The offset was out of the bounds of this"
447
488
          + " buffer", offset);
448
489
 
 
490
    clearPositionReferences();
 
491
 
449
492
    // We store the actual array index in the GapContentPosition. The real
450
493
    // offset is then calculated in the GapContentPosition.
451
494
    int mark = offset;
452
 
    if (offset > gapStart)
 
495
    if (offset >= gapStart)
453
496
      mark += gapEnd - gapStart;
454
497
    GapContentPosition pos = new GapContentPosition(mark);
 
498
    WeakReference r = new WeakReference(pos);
455
499
 
456
500
    // Add this into our list in a sorted fashion.
457
 
    int index = Collections.binarySearch(positions, pos);
 
501
    int index = Collections.binarySearch(positions, r,
 
502
                                         new WeakPositionComparator());
458
503
    if (index < 0)
459
504
      index = -(index + 1);
460
 
    positions.add(index, pos);
 
505
    positions.add(index, r);
461
506
    return pos;
462
507
  }
463
508
 
557
602
 
558
603
    assert newGapEnd > gapEnd : "The new gap end must be greater than the "
559
604
                                + "old gap end.";
560
 
    setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd + 1);
 
605
    setPositionsInRange(gapEnd, newGapEnd - gapEnd, newGapEnd);
561
606
    gapEnd = newGapEnd;
562
607
  }
563
608
 
566
611
   * 
567
612
   * @return the allocated buffer array
568
613
   */
569
 
  protected Object getArray()
 
614
  protected final Object getArray()
570
615
  {
571
616
    return buffer;
572
617
  }
584
629
  {
585
630
    if (gapStart != position)
586
631
      shiftGap(position);
 
632
      
587
633
    // Remove content
588
 
    if (rmSize > 0)
 
634
    if (rmSize > 0) 
589
635
      shiftGapEndUp(gapEnd + rmSize);
590
636
 
591
637
    // If gap is too small, enlarge the gap.
596
642
    if (addItems != null)
597
643
      {
598
644
        System.arraycopy(addItems, 0, buffer, gapStart, addSize);
 
645
        
 
646
        
 
647
        resetMarksAtZero();
 
648
        
599
649
        gapStart += addSize;
600
650
      }
601
651
  }
641
691
    int endOffset = offset + length;
642
692
 
643
693
    int index1 = Collections.binarySearch(positions,
644
 
                                          new GapContentPosition(offset));
 
694
                                          new GapContentPosition(offset),
 
695
                                          new WeakPositionComparator());
645
696
    if (index1 < 0)
646
697
      index1 = -(index1 + 1);
 
698
 
 
699
    // Search the first index with the specified offset. The binarySearch does
 
700
    // not necessarily find the first one.
 
701
    while (index1 > 0)
 
702
      {
 
703
        WeakReference r = (WeakReference) positions.get(index1 - 1);
 
704
        GapContentPosition p = (GapContentPosition) r.get();
 
705
        if (p != null && p.mark == offset || p == null)
 
706
          index1--;
 
707
        else
 
708
          break;
 
709
      }
 
710
 
647
711
    for (ListIterator i = positions.listIterator(index1); i.hasNext();)
648
712
      {
649
 
        GapContentPosition p = (GapContentPosition) i.next();
 
713
        WeakReference r = (WeakReference) i.next();
 
714
        GapContentPosition p = (GapContentPosition) r.get();
 
715
        if (p == null)
 
716
          continue;
 
717
 
650
718
        if (p.mark > endOffset)
651
719
          break;
652
720
        if (p.mark >= offset && p.mark <= endOffset)
664
732
   * @param length the length of the range to search
665
733
   * @param value the new value for each mark
666
734
   */
667
 
  void setPositionsInRange(int offset, int length, int value)
 
735
  private void setPositionsInRange(int offset, int length, int value)
668
736
  {
669
737
    int endOffset = offset + length;
670
738
 
671
739
    int index1 = Collections.binarySearch(positions,
672
 
                                          new GapContentPosition(offset));
 
740
                                          new GapContentPosition(offset),
 
741
                                          new WeakPositionComparator());
673
742
    if (index1 < 0)
674
743
      index1 = -(index1 + 1);
 
744
 
 
745
    // Search the first index with the specified offset. The binarySearch does
 
746
    // not necessarily find the first one.
 
747
    while (index1 > 0)
 
748
      {
 
749
        WeakReference r = (WeakReference) positions.get(index1 - 1);
 
750
        GapContentPosition p = (GapContentPosition) r.get();
 
751
        if (p != null && p.mark == offset || p == null)
 
752
          index1--;
 
753
        else
 
754
          break;
 
755
      }
 
756
 
675
757
    for (ListIterator i = positions.listIterator(index1); i.hasNext();)
676
758
      {
677
 
        GapContentPosition p = (GapContentPosition) i.next();
 
759
        WeakReference r = (WeakReference) i.next();
 
760
        GapContentPosition p = (GapContentPosition) r.get();
 
761
        if (p == null)
 
762
          continue;
 
763
 
678
764
        if (p.mark > endOffset)
679
765
          break;
680
766
        
692
778
   * @param length the length of the range to search
693
779
   * @param incr the increment
694
780
   */
695
 
  void adjustPositionsInRange(int offset, int length, int incr)
 
781
  private void adjustPositionsInRange(int offset, int length, int incr)
696
782
  {
697
783
    int endOffset = offset + length;
698
784
 
699
785
    int index1 = Collections.binarySearch(positions,
700
 
                                          new GapContentPosition(offset));
 
786
                                          new GapContentPosition(offset),
 
787
                                          new WeakPositionComparator());
701
788
    if (index1 < 0)
702
789
      index1 = -(index1 + 1);
 
790
 
 
791
    // Search the first index with the specified offset. The binarySearch does
 
792
    // not necessarily find the first one.
 
793
    while (index1 > 0)
 
794
      {
 
795
        WeakReference r = (WeakReference) positions.get(index1 - 1);
 
796
        GapContentPosition p = (GapContentPosition) r.get();
 
797
        if (p != null && p.mark == offset || p == null)
 
798
          index1--;
 
799
        else
 
800
          break;
 
801
      }
 
802
 
703
803
    for (ListIterator i = positions.listIterator(index1); i.hasNext();)
704
804
      {
705
 
        GapContentPosition p = (GapContentPosition) i.next();
 
805
        WeakReference r = (WeakReference) i.next();
 
806
        GapContentPosition p = (GapContentPosition) r.get();
 
807
        if (p == null)
 
808
          continue;
 
809
 
706
810
        if (p.mark > endOffset)
707
811
          break;
708
812
 
726
830
  }
727
831
 
728
832
  /**
 
833
   * @specnote This method is not very well specified and the positions vector
 
834
   *           is implementation specific. The undo positions are managed
 
835
   *           differently in this implementation, this method is only here
 
836
   *           for binary compatibility.
 
837
   */
 
838
  protected void updateUndoPositions(Vector positions, int offset, int length)
 
839
  {
 
840
    // We do nothing here.
 
841
  }
 
842
 
 
843
  /**
729
844
   * Outputs debugging info to System.err. It prints out the buffer array,
730
845
   * the gapStart is marked by a &lt; sign, the gapEnd is marked by a &gt;
731
846
   * sign and each position is marked by a # sign.
755
870
  {
756
871
    for (Iterator i = positions.iterator(); i.hasNext();)
757
872
      {
758
 
        GapContentPosition pos = (GapContentPosition) i.next();
 
873
        WeakReference r = (WeakReference) i.next();
 
874
        GapContentPosition pos = (GapContentPosition) r.get();
759
875
        System.err.println("position at: " + pos.mark);
760
876
      }
761
877
  }
 
878
 
 
879
  /**
 
880
   * Clears all GC'ed references in the positions array.
 
881
   */
 
882
  private void clearPositionReferences()
 
883
  {
 
884
    Iterator i = positions.iterator();
 
885
    while (i.hasNext())
 
886
      {
 
887
        WeakReference r = (WeakReference) i.next();
 
888
        if (r.get() == null)
 
889
          i.remove();
 
890
      }
 
891
  }
762
892
}