KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > lists > SeqPosition


1 // Copyright (c) 2001, 2002, 2003 Per M.A. Bothner and Brainfood Inc.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3
package gnu.lists;
4
5 import java.util.NoSuchElementException JavaDoc;
6
7 /**
8  * A position in a sequence (list).
9  *
10  * Conceptually similar to Java2's ListIterator, but we use the name "Position"
11  * to indicate that it can be used to both indicate a position in a sequence
12  * and to iterate through a sequence. If you use a SeqPosition as a
13  * "position", you would not modify if (though it is possible the offset
14  * of the position in the sequence may change due to other update operations
15  * on the sequence). If you use a SeqPosition as an "iterator", you would
16  * initialize it to some beginnning position, and then modify the current
17  * position of the SeqPosition so it refers to successive elements.
18  *
19  * See the <a HREF="package-summary.html#iteration">package overview</a>
20  * for more information.
21  */

22
23 public class SeqPosition
24 implements
25     /* #ifdef JAVA2 */
26     java.util.ListIterator JavaDoc,
27     /* #endif */
28     java.util.Enumeration JavaDoc
29 {
30   /**
31    * The Sequence relative to which ipos and xpos have meaning.
32    * This is normally the same as the Sequence we iterate through.
33    * However, if this is a TreePosition, it may an ancestor instead.
34    */

35   public AbstractSequence sequence;
36
37   /**
38    * An integer that (together with xpos) indicates the current position.
39    * The actual value has no meaning, except as interpreted by sequence.
40    */

41   public int ipos;
42
43   public SeqPosition()
44   {
45   }
46
47   public SeqPosition(AbstractSequence seq)
48   {
49     this.sequence = seq;
50   }
51
52   public SeqPosition(AbstractSequence seq, int offset, boolean isAfter)
53   {
54     this.sequence = seq;
55     ipos = seq.createPos(offset, isAfter);
56   }
57
58   public SeqPosition(AbstractSequence seq, int ipos)
59   {
60     this.sequence = seq;
61     this.ipos = ipos;
62   }
63
64   /** Creates a new SeqPosition, from a position pair.
65    * The position pair is copied (using copyPos).
66    */

67   public static SeqPosition make(AbstractSequence seq, int ipos)
68   {
69     return new SeqPosition(seq, seq.copyPos(ipos));
70   }
71
72   public SeqPosition copy ()
73   {
74     return new SeqPosition(sequence, sequence.copyPos(getPos()));
75   }
76  
77   public final void gotoStart(AbstractSequence seq)
78   {
79     setPos(seq, seq.startPos());
80   }
81
82   public final void gotoEnd(AbstractSequence seq)
83   {
84     setPos(seq, seq.endPos());
85   }
86
87   /** Set position before first child (of the element following position).
88    * @return true if there is a child sequence (which might be empty);
89    * false if current position is end of sequence or following element
90    * is atomic (cannot have children).
91    */

92   public boolean gotoChildrenStart()
93   {
94     int child = sequence.firstChildPos(getPos());
95     if (child == 0)
96       return false;
97     ipos = child;
98     return true;
99   }
100
101   /** True if there is an element following the current position.
102    * False if we are at the end. See java.util.Enumeration. */

103   public final boolean hasMoreElements()
104   {
105     return hasNext();
106   }
107
108   /** See java.util.Iterator. */
109   public boolean hasNext()
110   {
111     return sequence.hasNext(getPos());
112   }
113
114   /** Return a code (defined in Sequence) for the type of the next element. */
115   public int getNextKind()
116   {
117     return sequence.getNextKind(getPos());
118   }
119
120   /** Get the "tag name" for the next element, if any. */
121   public String JavaDoc getNextTypeName()
122   {
123     return sequence.getNextTypeName(getPos());
124   }
125
126   /** Get the "tag object" for the next element, if any. */
127   public Object JavaDoc getNextTypeObject()
128   {
129     return sequence.getNextTypeObject(getPos());
130   }
131
132   /** See java.util.Iterator. */
133   public boolean hasPrevious()
134   {
135     return sequence.hasPrevious(getPos());
136   }
137
138   /** See java.util.ListIterator. */
139   public Object JavaDoc next()
140   {
141     Object JavaDoc result = getNext();
142     if (result == Sequence.eofValue || ! gotoNext())
143       throw new NoSuchElementException JavaDoc();
144     return result;
145   }
146
147   /** Move one element forwards, if possible.
148    * @return if we succeeded in moving forwards (i.e. not at end of sequence).
149    */

150   public boolean gotoNext()
151   {
152     int next = sequence.nextPos(ipos);
153     if (next != 0)
154       {
155     ipos = next;
156     return true;
157       }
158     else
159       {
160     ipos = -1;
161     return false;
162       }
163   }
164
165   /** Move backwards one element.
166    * @return false iff already at beginning.
167    */

168   public boolean gotoPrevious()
169   {
170     int prev = sequence.previousPos(ipos);
171     if (prev != -1)
172       {
173     ipos = prev;
174     return true;
175       }
176     else
177       {
178     ipos = 0;
179     return false;
180       }
181   }
182
183   /** See java.util.ListIterator. */
184   public Object JavaDoc previous()
185   {
186     Object JavaDoc result = getPrevious();
187     if (result == Sequence.eofValue || ! gotoPrevious())
188       throw new NoSuchElementException JavaDoc();
189     return result;
190   }
191
192   /** See java.util.Enumeration. */
193   public final Object JavaDoc nextElement()
194   {
195     return next();
196   }
197
198   /**
199    * Get element following current position.
200    * Does not move the position, in contrast to next() method.
201    * @return EOF if at end of sequence, otherwise the value following.
202    */

203   public Object JavaDoc getNext()
204   {
205     return sequence.getPosNext(getPos());
206   }
207
208   /**
209    * Get element before the current position.
210    * Does not move the position, in contrast to previous() method.
211    * @return EOF if at beginning of sequence, otherwise the value prior.
212    */

213   public Object JavaDoc getPrevious()
214   {
215     return sequence.getPosPrevious(getPos());
216   }
217
218   /** See java.util.Iterator. */
219   public int nextIndex()
220   {
221     return sequence.nextIndex(getPos());
222   }
223
224   public final int fromEndIndex()
225   {
226     return sequence.fromEndIndex(getPos());
227   }
228
229   public int getContainingSequenceSize()
230   {
231     return sequence.getContainingSequenceSize(getPos());
232   }
233
234   /** See java.util.Iterator. */
235   public final int previousIndex()
236   {
237     return sequence.nextIndex(getPos()) - 1;
238   }
239
240   /** Tests whether the position pair has the "isAfter" property.
241    * I.e. if something is inserted at the position, will
242    * the iterator end up being after the new data?
243    * A toNext() or next() command should set isAfter() to true;
244    * a toPrevious or previous command should set isAfter() to false.
245    */

246   public boolean isAfter()
247   {
248     return sequence.isAfterPos(getPos());
249   }
250
251   public final void set(Object JavaDoc value)
252   {
253     if (isAfter())
254       setPrevious(value);
255     else
256       setNext(value);
257   }
258
259   public void setNext (Object JavaDoc value)
260   {
261     sequence.setPosNext(getPos(), value);
262   }
263
264   public void setPrevious (Object JavaDoc value)
265   {
266     sequence.setPosPrevious(getPos(), value);
267   }
268
269   public void remove()
270   {
271     sequence.removePos(getPos(), isAfter() ? -1 : 1);
272   }
273
274   public void add(Object JavaDoc o)
275   {
276     setPos(sequence.addPos(getPos(), o));
277   }
278
279   /** Get a position int "cookie" for this SeqPosition.
280    * The result can be passed to AbstractSequence's getPosNext(int),
281    * createRelativePos, and other methods.
282    * By default this is the value of ipos, but for sequences that need emore
283    * state than an ipos for efficient position, we use a PositionManager index.
284    * So this gets over-ridden in ExtPosition.
285    */

286   public int getPos ()
287   {
288     return ipos;
289   }
290
291   public void setPos (AbstractSequence seq, int ipos)
292   {
293     if (sequence != null)
294       sequence.releasePos(getPos());
295     this.ipos = ipos;
296     this.sequence = seq;
297   }
298
299   public void setPos (int ipos)
300   {
301     if (sequence != null)
302       sequence.releasePos(getPos());
303     this.ipos = ipos;
304   }
305
306   public void set (AbstractSequence seq, int index, boolean isAfter)
307   {
308     if (sequence != null)
309       sequence.releasePos(ipos);
310     sequence = seq;
311     ipos = seq.createPos(index, isAfter);
312   }
313
314   public void set (SeqPosition pos)
315   {
316     if (sequence != null)
317       sequence.releasePos(ipos);
318     sequence = pos.sequence;
319     pos.ipos = sequence.copyPos(pos.ipos);
320   }
321
322   public void release()
323   {
324     if (sequence != null)
325       {
326     sequence.releasePos(getPos());
327     sequence = null;
328       }
329   }
330
331   public void finalize()
332   {
333     release();
334   }
335
336   public String JavaDoc toString()
337   {
338     if (sequence == null)
339       return toInfo();
340     Object JavaDoc item = sequence.getPosNext(ipos);
341     if (item == null)
342       return toInfo();
343     return item.toString();
344   }
345
346   public String JavaDoc toInfo()
347   {
348     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc(60);
349     sbuf.append('{');
350     if (sequence == null)
351       sbuf.append("null sequence");
352     else
353       {
354     sbuf.append(sequence.getClass().getName());
355     sbuf.append('@');
356     sbuf.append(System.identityHashCode(sequence));
357       }
358     sbuf.append(" ipos: ");
359     sbuf.append(ipos);
360     /*
361     if (sequence instanceof TreeList)
362       {
363     sbuf.append(" index: ");
364     sbuf.append(((TreeList) sequence).posToDataIndex(ipos));
365       }
366     */

367     sbuf.append('}');
368     return sbuf.toString();
369   }
370 }
371 // This is for people using the Emacs editor:
372
// Local Variables:
373
// c-file-style: "gnu"
374
// tab-width: 8
375
// indent-tabs-mode: t
376
// End:
377
Popular Tags