| /* AttributedString.java -- Models text with attributes |
| Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package java.text; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * This class models a <code>String</code> with attributes over various |
| * subranges of the string. It allows applications to access this |
| * information via the <code>AttributedCharcterIterator</code> interface. |
| * |
| * @version 0.0 |
| * |
| * @author Aaron M. Renn (arenn@urbanophile.com) |
| */ |
| public class AttributedString |
| { |
| |
| /*************************************************************************/ |
| |
| /* |
| * Inner Classes |
| */ |
| |
| /** |
| * This class contains the attributes and ranges of text over which |
| * that attributes apply. |
| */ |
| final class AttributeRange |
| { |
| |
| /* |
| * Instance Variables |
| */ |
| |
| /** |
| * A Map of the attributes |
| */ |
| Map attribs; |
| |
| /** |
| * The beginning index of the attributes |
| */ |
| int begin_index; |
| |
| /** |
| * The ending index of the attributes |
| */ |
| int end_index; |
| |
| /*************************************************************************/ |
| |
| /* |
| * Constructors |
| */ |
| |
| AttributeRange(Map attribs, int begin_index, int end_index) |
| { |
| this.attribs = attribs; |
| this.begin_index = begin_index; |
| this.end_index = end_index; |
| } |
| |
| } // Inner class AttributeRange |
| |
| /*************************************************************************/ |
| |
| /* |
| * Instance Variables |
| */ |
| |
| /** |
| * This object holds the string we are representing. |
| */ |
| private StringCharacterIterator sci; |
| |
| /** |
| * This is the attribute information |
| */ |
| private AttributeRange[] attribs; |
| |
| /*************************************************************************/ |
| |
| /* |
| * Constructors |
| */ |
| |
| /** |
| * This method initializes a new instance of <code>AttributedString</code> |
| * that represents the specified <code>String</code> with no attributes. |
| * |
| * @param str The <code>String</code> to be attributed. |
| */ |
| public |
| AttributedString(String str) |
| { |
| sci = new StringCharacterIterator(str); |
| attribs = new AttributeRange[0]; |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method initializes a new instance of <code>AttributedString</code> |
| * that represents that specified <code>String</code> with the specified |
| * attributes over the entire length of the <code>String</code>. |
| * |
| * @param str The <code>String</code> to be attributed. |
| * @param attributes The attribute list. |
| */ |
| public |
| AttributedString(String str, Map attributes) |
| { |
| this(str); |
| |
| attribs = new AttributeRange[1]; |
| attribs[0] = new AttributeRange(attributes, 0, str.length()); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method initializes a new instance of <code>AttributedString</code> |
| * that will use the text and attribute information from the specified |
| * <code>AttributedCharacterIterator</code>. |
| * |
| * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. |
| */ |
| public |
| AttributedString(AttributedCharacterIterator aci) |
| { |
| this(aci, aci.getBeginIndex(), aci.getEndIndex(), null); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method initializes a new instance of <code>AttributedString</code> |
| * that will use the text and attribute information from the specified |
| * subrange of the specified <code>AttributedCharacterIterator</code>. |
| * |
| * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. |
| * @param begin_index The beginning index of the text subrange. |
| * @param end_index The ending index of the text subrange. |
| */ |
| public |
| AttributedString(AttributedCharacterIterator aci, int begin_index, |
| int end_index) |
| { |
| this(aci, begin_index, end_index, null); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method initializes a new instance of <code>AttributedString</code> |
| * that will use the text and attribute information from the specified |
| * subrange of the specified <code>AttributedCharacterIterator</code>. |
| * Only attributes from the source iterator that are present in the |
| * specified array of attributes will be included in the attribute list |
| * for this object. |
| * |
| * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. |
| * @param begin_index The beginning index of the text subrange. |
| * @param end_index The ending index of the text subrange. |
| * @param attributes A list of attributes to include from the iterator, or <code>null</code> to include all attributes. |
| */ |
| public |
| AttributedString(AttributedCharacterIterator aci, int begin_index, |
| int end_index, AttributedCharacterIterator.Attribute[] attributes) |
| { |
| // Validate some arguments |
| if ((begin_index < 0) || (end_index < begin_index)) |
| throw new IllegalArgumentException("Bad index values"); |
| |
| StringBuffer sb = new StringBuffer(""); |
| |
| // Get the valid attribute list |
| Set all_attribs = aci.getAllAttributeKeys(); |
| if (attributes != null) |
| all_attribs.retainAll(Arrays.asList(attributes)); |
| |
| // Loop through and extract the attributes |
| char c = aci.setIndex(begin_index); |
| |
| ArrayList accum = new ArrayList(); |
| do |
| { |
| sb.append(c); |
| |
| Iterator iter = all_attribs.iterator(); |
| while(iter.hasNext()) |
| { |
| Object obj = iter.next(); |
| |
| // What should we do if this is not true? |
| if (!(obj instanceof AttributedCharacterIterator.Attribute)) |
| continue; |
| |
| AttributedCharacterIterator.Attribute attrib = |
| (AttributedCharacterIterator.Attribute)obj; |
| |
| // Make sure the attribute is defined. |
| int rl = aci.getRunLimit(attrib); |
| if (rl == -1) |
| continue; |
| if (rl > end_index) |
| rl = end_index; |
| rl -= begin_index; |
| |
| // Check to see if we already processed this one |
| int rs = aci.getRunStart(attrib); |
| if ((rs < aci.getIndex()) && (aci.getIndex() != begin_index)) |
| continue; |
| |
| // If the attribute run starts before the beginning index, we |
| // need to junk it if it is an Annotation. |
| Object attrib_obj = aci.getAttribute(attrib); |
| if (rs < begin_index) |
| { |
| if (attrib_obj instanceof Annotation) |
| continue; |
| |
| rs = begin_index; |
| } |
| else |
| { |
| rs -= begin_index; |
| } |
| |
| // Create a map object. Yes this will only contain one attribute |
| Map new_map = new Hashtable(); |
| new_map.put(attrib, attrib_obj); |
| |
| // Add it to the attribute list. |
| accum.add(new AttributeRange(new_map, rs, rl)); |
| } |
| |
| c = aci.next(); |
| } |
| while(c != CharacterIterator.DONE); |
| |
| attribs = new AttributeRange[accum.size()]; |
| attribs = (AttributeRange[]) accum.toArray(attribs); |
| |
| sci = new StringCharacterIterator(sb.toString()); |
| } |
| |
| /*************************************************************************/ |
| |
| /* |
| * Instance Methods |
| */ |
| |
| /** |
| * This method adds a new attribute that will cover the entire string. |
| * |
| * @param attrib The attribute to add. |
| * @param value The value of the attribute. |
| */ |
| public void |
| addAttribute(AttributedCharacterIterator.Attribute attrib, Object value) |
| { |
| addAttribute(attrib, value, 0, sci.getEndIndex()); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method adds a new attribute that will cover the specified subrange |
| * of the string. |
| * |
| * @param attrib The attribute to add. |
| * @param value The value of the attribute, which may be null. |
| * @param begin_index The beginning index of the subrange. |
| * @param end_index The ending index of the subrange. |
| * |
| * @exception IllegalArgumentException If attribute is <code>null</code> or the subrange is not valid. |
| */ |
| public void |
| addAttribute(AttributedCharacterIterator.Attribute attrib, Object value, |
| int begin_index, int end_index) |
| { |
| if (attrib == null) |
| throw new IllegalArgumentException("null attribute"); |
| |
| HashMap hm = new HashMap(); |
| hm.put(attrib, value); |
| |
| addAttributes(hm, begin_index, end_index); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method adds all of the attributes in the specified list to the |
| * specified subrange of the string. |
| * |
| * @param attributes The list of attributes. |
| * @param begin_index The beginning index. |
| * @param end_index The ending index |
| * |
| * @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid. |
| */ |
| public void |
| addAttributes(Map attributes, int begin_index, int end_index) |
| { |
| if (attributes == null) |
| throw new IllegalArgumentException("null attribute"); |
| |
| if ((begin_index < 0) || (end_index > sci.getEndIndex()) || |
| (end_index < begin_index)) |
| throw new IllegalArgumentException("bad range"); |
| |
| AttributeRange[] new_list = new AttributeRange[attribs.length + 1]; |
| System.arraycopy(attribs, 0, new_list, 0, attribs.length); |
| attribs = new_list; |
| attribs[attribs.length - 1] = new AttributeRange(attributes, begin_index, |
| end_index); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method returns an <code>AttributedCharacterIterator</code> that |
| * will iterate over the entire string. |
| * |
| * @return An <code>AttributedCharacterIterator</code> for the entire string. |
| */ |
| public AttributedCharacterIterator |
| getIterator() |
| { |
| return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex(), null)); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method returns an <code>AttributedCharacterIterator</code> that |
| * will iterate over the entire string. This iterator will return information |
| * about the list of attributes in the specified array. Attributes not in |
| * the array may or may not be returned by the iterator. If the specified |
| * array is <code>null</code>, all attributes will be returned. |
| * |
| * @param attributes A list of attributes to include in the returned iterator. |
| * |
| * @return An <code>AttributedCharacterIterator</code> for this string. |
| */ |
| public AttributedCharacterIterator |
| getIterator(AttributedCharacterIterator.Attribute[] attributes) |
| { |
| return(getIterator(attributes, 0, sci.getEndIndex())); |
| } |
| |
| /*************************************************************************/ |
| |
| /** |
| * This method returns an <code>AttributedCharacterIterator</code> that |
| * will iterate over the specified subrange. This iterator will return information |
| * about the list of attributes in the specified array. Attributes not in |
| * the array may or may not be returned by the iterator. If the specified |
| * array is <code>null</code>, all attributes will be returned. |
| * |
| * @param attributes A list of attributes to include in the returned iterator. |
| * @param begin_index The beginning index of the subrange. |
| * @param end_index The ending index of the subrange. |
| * |
| * @return An <code>AttributedCharacterIterator</code> for this string. |
| */ |
| public AttributedCharacterIterator |
| getIterator(AttributedCharacterIterator.Attribute[] attributes, |
| int begin_index, int end_index) |
| { |
| if ((begin_index < 0) || (end_index > sci.getEndIndex()) || |
| (end_index < begin_index)) |
| throw new IllegalArgumentException("bad range"); |
| |
| return(new AttributedStringIterator(sci, attribs, begin_index, end_index, |
| attributes)); |
| } |
| |
| } // class AttributedString |
| |