1 /* AttributedString.java -- Models text with attributes
2 Copyright (C) 1998, 1999, 2004 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., 59 Temple Place, Suite 330, 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
.ArrayList
;
42 import java
.util
.Arrays
;
43 import java
.util
.HashMap
;
44 import java
.util
.Hashtable
;
45 import java
.util
.Iterator
;
50 * This class models a <code>String</code> with attributes over various
51 * subranges of the string. It allows applications to access this
52 * information via the <code>AttributedCharcterIterator</code> interface.
56 * @author Aaron M. Renn (arenn@urbanophile.com)
58 public class AttributedString
61 /*************************************************************************/
68 * This class contains the attributes and ranges of text over which
69 * that attributes apply.
71 final class AttributeRange
79 * A Map of the attributes
84 * The beginning index of the attributes
89 * The ending index of the attributes
93 /*************************************************************************/
99 AttributeRange(Map attribs
, int begin_index
, int end_index
)
101 this.attribs
= attribs
;
102 this.begin_index
= begin_index
;
103 this.end_index
= end_index
;
106 } // Inner class AttributeRange
108 /*************************************************************************/
115 * This object holds the string we are representing.
117 private StringCharacterIterator sci
;
120 * This is the attribute information
122 private AttributeRange
[] attribs
;
124 /*************************************************************************/
131 * This method initializes a new instance of <code>AttributedString</code>
132 * that represents the specified <code>String</code> with no attributes.
134 * @param str The <code>String</code> to be attributed.
137 AttributedString(String str
)
139 sci
= new StringCharacterIterator(str
);
140 attribs
= new AttributeRange
[0];
143 /*************************************************************************/
146 * This method initializes a new instance of <code>AttributedString</code>
147 * that represents that specified <code>String</code> with the specified
148 * attributes over the entire length of the <code>String</code>.
150 * @param str The <code>String</code> to be attributed.
151 * @param attributes The attribute list.
154 AttributedString(String str
, Map attributes
)
158 attribs
= new AttributeRange
[1];
159 attribs
[0] = new AttributeRange(attributes
, 0, str
.length());
162 /*************************************************************************/
165 * This method initializes a new instance of <code>AttributedString</code>
166 * that will use the text and attribute information from the specified
167 * <code>AttributedCharacterIterator</code>.
169 * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
172 AttributedString(AttributedCharacterIterator aci
)
174 this(aci
, aci
.getBeginIndex(), aci
.getEndIndex(), null);
177 /*************************************************************************/
180 * This method initializes a new instance of <code>AttributedString</code>
181 * that will use the text and attribute information from the specified
182 * subrange of the specified <code>AttributedCharacterIterator</code>.
184 * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
185 * @param begin_index The beginning index of the text subrange.
186 * @param end_index The ending index of the text subrange.
189 AttributedString(AttributedCharacterIterator aci
, int begin_index
,
192 this(aci
, begin_index
, end_index
, null);
195 /*************************************************************************/
198 * This method initializes a new instance of <code>AttributedString</code>
199 * that will use the text and attribute information from the specified
200 * subrange of the specified <code>AttributedCharacterIterator</code>.
201 * Only attributes from the source iterator that are present in the
202 * specified array of attributes will be included in the attribute list
205 * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information.
206 * @param begin_index The beginning index of the text subrange.
207 * @param end_index The ending index of the text subrange.
208 * @param attributes A list of attributes to include from the iterator, or <code>null</code> to include all attributes.
211 AttributedString(AttributedCharacterIterator aci
, int begin_index
,
212 int end_index
, AttributedCharacterIterator
.Attribute
[] attributes
)
214 // Validate some arguments
215 if ((begin_index
< 0) || (end_index
< begin_index
))
216 throw new IllegalArgumentException("Bad index values");
218 StringBuffer sb
= new StringBuffer("");
220 // Get the valid attribute list
221 Set all_attribs
= aci
.getAllAttributeKeys();
222 if (attributes
!= null)
223 all_attribs
.retainAll(Arrays
.asList(attributes
));
225 // Loop through and extract the attributes
226 char c
= aci
.setIndex(begin_index
);
228 ArrayList accum
= new ArrayList();
233 Iterator iter
= all_attribs
.iterator();
234 while(iter
.hasNext())
236 Object obj
= iter
.next();
238 // What should we do if this is not true?
239 if (!(obj
instanceof AttributedCharacterIterator
.Attribute
))
242 AttributedCharacterIterator
.Attribute attrib
=
243 (AttributedCharacterIterator
.Attribute
)obj
;
245 // Make sure the attribute is defined.
246 int rl
= aci
.getRunLimit(attrib
);
253 // Check to see if we already processed this one
254 int rs
= aci
.getRunStart(attrib
);
255 if ((rs
< aci
.getIndex()) && (aci
.getIndex() != begin_index
))
258 // If the attribute run starts before the beginning index, we
259 // need to junk it if it is an Annotation.
260 Object attrib_obj
= aci
.getAttribute(attrib
);
261 if (rs
< begin_index
)
263 if (attrib_obj
instanceof Annotation
)
273 // Create a map object. Yes this will only contain one attribute
274 Map new_map
= new Hashtable();
275 new_map
.put(attrib
, attrib_obj
);
277 // Add it to the attribute list.
278 accum
.add(new AttributeRange(new_map
, rs
, rl
));
283 while(c
!= CharacterIterator
.DONE
);
285 attribs
= new AttributeRange
[accum
.size()];
286 attribs
= (AttributeRange
[]) accum
.toArray(attribs
);
288 sci
= new StringCharacterIterator(sb
.toString());
291 /*************************************************************************/
298 * This method adds a new attribute that will cover the entire string.
300 * @param attrib The attribute to add.
301 * @param value The value of the attribute.
304 addAttribute(AttributedCharacterIterator
.Attribute attrib
, Object value
)
306 addAttribute(attrib
, value
, 0, sci
.getEndIndex());
309 /*************************************************************************/
312 * This method adds a new attribute that will cover the specified subrange
315 * @param attrib The attribute to add.
316 * @param value The value of the attribute, which may be null.
317 * @param begin_index The beginning index of the subrange.
318 * @param end_index The ending index of the subrange.
320 * @exception IllegalArgumentException If attribute is <code>null</code> or the subrange is not valid.
323 addAttribute(AttributedCharacterIterator
.Attribute attrib
, Object value
,
324 int begin_index
, int end_index
)
327 throw new IllegalArgumentException("null attribute");
329 HashMap hm
= new HashMap();
330 hm
.put(attrib
, value
);
332 addAttributes(hm
, begin_index
, end_index
);
335 /*************************************************************************/
338 * This method adds all of the attributes in the specified list to the
339 * specified subrange of the string.
341 * @param attributes The list of attributes.
342 * @param begin_index The beginning index.
343 * @param end_index The ending index
345 * @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid.
348 addAttributes(Map attributes
, int begin_index
, int end_index
)
350 if (attributes
== null)
351 throw new IllegalArgumentException("null attribute");
353 if ((begin_index
< 0) || (end_index
> sci
.getEndIndex()) ||
354 (end_index
< begin_index
))
355 throw new IllegalArgumentException("bad range");
357 AttributeRange
[] new_list
= new AttributeRange
[attribs
.length
+ 1];
358 System
.arraycopy(attribs
, 0, new_list
, 0, attribs
.length
);
360 attribs
[attribs
.length
- 1] = new AttributeRange(attributes
, begin_index
,
364 /*************************************************************************/
367 * This method returns an <code>AttributedCharacterIterator</code> that
368 * will iterate over the entire string.
370 * @return An <code>AttributedCharacterIterator</code> for the entire string.
372 public AttributedCharacterIterator
375 return(new AttributedStringIterator(sci
, attribs
, 0, sci
.getEndIndex(), null));
378 /*************************************************************************/
381 * This method returns an <code>AttributedCharacterIterator</code> that
382 * will iterate over the entire string. This iterator will return information
383 * about the list of attributes in the specified array. Attributes not in
384 * the array may or may not be returned by the iterator. If the specified
385 * array is <code>null</code>, all attributes will be returned.
387 * @param attributes A list of attributes to include in the returned iterator.
389 * @return An <code>AttributedCharacterIterator</code> for this string.
391 public AttributedCharacterIterator
392 getIterator(AttributedCharacterIterator
.Attribute
[] attributes
)
394 return(getIterator(attributes
, 0, sci
.getEndIndex()));
397 /*************************************************************************/
400 * This method returns an <code>AttributedCharacterIterator</code> that
401 * will iterate over the specified subrange. This iterator will return information
402 * about the list of attributes in the specified array. Attributes not in
403 * the array may or may not be returned by the iterator. If the specified
404 * array is <code>null</code>, all attributes will be returned.
406 * @param attributes A list of attributes to include in the returned iterator.
407 * @param begin_index The beginning index of the subrange.
408 * @param end_index The ending index of the subrange.
410 * @return An <code>AttributedCharacterIterator</code> for this string.
412 public AttributedCharacterIterator
413 getIterator(AttributedCharacterIterator
.Attribute
[] attributes
,
414 int begin_index
, int end_index
)
416 if ((begin_index
< 0) || (end_index
> sci
.getEndIndex()) ||
417 (end_index
< begin_index
))
418 throw new IllegalArgumentException("bad range");
420 return(new AttributedStringIterator(sci
, attribs
, begin_index
, end_index
,
424 } // class AttributedString