1 /* AttributedStringIterator.java -- Class to iterate over AttributedString
2 Copyright (C) 1998, 1999, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.util
.HashMap
;
42 import java
.util
.HashSet
;
43 import java
.util
.Iterator
;
48 * This class implements the AttributedCharacterIterator interface. It
49 * is used by AttributedString.getIterator().
53 * @author Aaron M. Renn (arenn@urbanophile.com)
55 class AttributedStringIterator
implements AttributedCharacterIterator
58 /*************************************************************************/
60 /** The character iterator containing the text */
61 private CharacterIterator ci
;
63 /** The list of attributes and ranges */
64 private AttributedString
.AttributeRange
[] attribs
;
67 * The list of attributes that the user is interested in. We may,
68 * at our option, not return any other attributes.
70 private AttributedCharacterIterator
.Attribute
[] restricts
;
72 /*************************************************************************/
74 AttributedStringIterator(StringCharacterIterator sci
,
75 AttributedString
.AttributeRange
[] attribs
,
76 int begin_index
, int end_index
,
77 AttributedCharacterIterator
.Attribute
[] restricts
)
79 this.ci
= new StringCharacterIterator(sci
, begin_index
, end_index
);
80 this.attribs
= attribs
;
81 this.restricts
= restricts
;
84 /*************************************************************************/
86 // First we have a bunch of stupid redirects. If StringCharacterIterator
87 // weren't final, I just would have extended that for this class. Alas, no.
104 public char previous()
106 return(ci
.previous());
119 public int getIndex()
121 return(ci
.getIndex());
124 public char setIndex(int index
)
126 return(ci
.setIndex(index
));
129 public int getBeginIndex()
131 return(ci
.getBeginIndex());
134 public int getEndIndex()
136 return(ci
.getEndIndex());
140 * Here is where the AttributedCharacterIterator methods start.
143 /*************************************************************************/
146 * Returns a list of all the attribute keys that are defined anywhere
149 public Set
getAllAttributeKeys()
151 HashSet s
= new HashSet();
155 for (int i
= 0; i
< attribs
.length
; i
++)
157 if (attribs
[i
].begin_index
> getEndIndex()
158 || attribs
[i
].end_index
<= getBeginIndex())
161 Set key_set
= attribs
[i
].attribs
.keySet();
162 Iterator iter
= key_set
.iterator();
163 while (iter
.hasNext())
172 /*************************************************************************/
175 * Various methods that determine how far the run extends for various
176 * attribute combinations.
179 public int getRunLimit()
181 return(getRunLimit(getAttributes().keySet()));
184 public int getRunLimit(AttributedCharacterIterator
.Attribute attrib
)
186 HashSet s
= new HashSet();
188 return(getRunLimit(s
));
191 public synchronized int getRunLimit(Set attributeSet
)
193 if (attributeSet
== null)
194 return ci
.getEndIndex();
196 int current
= ci
.getIndex();
197 int end
= ci
.getEndIndex();
201 Map runValues
= getAttributes();
204 Iterator iterator
= attributeSet
.iterator();
205 while (iterator
.hasNext())
207 // Qualified name is a workaround for a gcj 4.0 bug.
208 AttributedCharacterIterator
.Attribute attributeKey
209 = (AttributedCharacterIterator
.Attribute
) iterator
.next();
210 Object v1
= runValues
.get(attributeKey
);
211 Object v2
= getAttribute(attributeKey
, limit
+ 1);
212 boolean changed
= false;
213 // check for equal or both null, if NO return start
216 changed
= !v1
.equals(v2
);
220 changed
= (v2
!= null);
225 // no differences, so increment limit and next and loop again
231 /*************************************************************************/
234 * Various methods that determine where the run begins for various
235 * attribute combinations.
239 * Returns the index of the first character in the run containing the current
240 * character and defined by all the attributes defined for that character
243 * @return The run start index.
245 public int getRunStart()
247 return(getRunStart(getAttributes().keySet()));
251 * Returns the index of the first character in the run, defined by the
252 * specified attribute, that contains the current character.
254 * @param attrib the attribute (<code>null</code> permitted).
256 * return The index of the first character in the run.
258 public int getRunStart(AttributedCharacterIterator
.Attribute attrib
)
261 return ci
.getBeginIndex();
262 HashSet s
= new HashSet();
264 return(getRunStart(s
));
268 * Returns the index of the first character in the run, defined by the
269 * specified attribute set, that contains the current character.
271 * @param attributeSet the attribute set (<code>null</code> permitted).
273 * return The index of the first character in the run.
275 public int getRunStart(Set attributeSet
)
277 if (attributeSet
== null)
278 return ci
.getBeginIndex();
280 int current
= ci
.getIndex();
281 int begin
= ci
.getBeginIndex();
285 Map runValues
= getAttributes();
286 int prev
= start
- 1;
287 while (start
> begin
)
289 Iterator iterator
= attributeSet
.iterator();
290 while (iterator
.hasNext())
292 // Qualified name is a workaround for a gcj 4.0 bug.
293 AttributedCharacterIterator
.Attribute attributeKey
294 = (AttributedCharacterIterator
.Attribute
) iterator
.next();
295 Object v1
= runValues
.get(attributeKey
);
296 Object v2
= getAttribute(attributeKey
, prev
);
297 boolean changed
= false;
298 // check for equal or both null, if NO return start
301 changed
= !v1
.equals(v2
);
305 changed
= (v2
!= null);
310 // no differences, so decrement start and prev and loop again
317 /*************************************************************************/
320 * Returns the value for an attribute at the specified position. If the
321 * attribute key (<code>key</code>) is <code>null</code>, the method returns
324 * @param key the key (<code>null</code> permitted).
325 * @param pos the character position.
327 * @return The attribute value (possibly <code>null</code>).
329 private Object
getAttribute(AttributedCharacterIterator
.Attribute key
,
334 for (int i
= attribs
.length
- 1; i
>= 0; i
--)
336 if (pos
>= attribs
[i
].begin_index
&& pos
< attribs
[i
].end_index
)
338 Set keys
= attribs
[i
].attribs
.keySet();
339 if (keys
.contains(key
))
341 return attribs
[i
].attribs
.get(key
);
349 * Returns the value for an attribute at the current position. If the
350 * attribute key (<code>key</code>) is <code>null</code>, the method returns
353 * @param key the key (<code>null</code> permitted).
355 * @return The attribute value (possibly <code>null</code>).
357 public Object
getAttribute(AttributedCharacterIterator
.Attribute key
)
359 return getAttribute(key
, ci
.getIndex());
362 /*************************************************************************/
365 * Return a list of all the attributes and values defined for this
368 public Map
getAttributes()
370 HashMap m
= new HashMap();
374 for (int i
= 0; i
< attribs
.length
; i
++)
376 if ((ci
.getIndex() >= attribs
[i
].begin_index
) &&
377 (ci
.getIndex() < attribs
[i
].end_index
))
378 m
.putAll(attribs
[i
].attribs
);
384 } // class AttributedStringIterator