GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* AttributedString.java -- Models text with attributes 2: Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 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) 9: any later version. 10: 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. 15: 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 19: 02110-1301 USA. 20: 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 24: combination. 25: 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. */ 37: 38: 39: package java.text; 40: 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; 46: import java.util.Map; 47: import java.util.Set; 48: 49: /** 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. 53: * 54: * @version 0.0 55: * 56: * @author Aaron M. Renn (arenn@urbanophile.com) 57: */ 58: public class AttributedString 59: { 60: 61: /*************************************************************************/ 62: 63: /* 64: * Inner Classes 65: */ 66: 67: /** 68: * This class contains the attributes and ranges of text over which 69: * that attributes apply. 70: */ 71: final class AttributeRange 72: { 73: 74: /* 75: * Instance Variables 76: */ 77: 78: /** 79: * A Map of the attributes 80: */ 81: Map attribs; 82: 83: /** 84: * The beginning index of the attributes 85: */ 86: int begin_index; 87: 88: /** 89: * The ending index of the attributes 90: */ 91: int end_index; 92: 93: /*************************************************************************/ 94: 95: /* 96: * Constructors 97: */ 98: 99: AttributeRange(Map attribs, int begin_index, int end_index) 100: { 101: this.attribs = attribs; 102: this.begin_index = begin_index; 103: this.end_index = end_index; 104: } 105: 106: } // Inner class AttributeRange 107: 108: /*************************************************************************/ 109: 110: /* 111: * Instance Variables 112: */ 113: 114: /** 115: * This object holds the string we are representing. 116: */ 117: private StringCharacterIterator sci; 118: 119: /** 120: * This is the attribute information 121: */ 122: private AttributeRange[] attribs; 123: 124: /*************************************************************************/ 125: 126: /* 127: * Constructors 128: */ 129: 130: /** 131: * This method initializes a new instance of <code>AttributedString</code> 132: * that represents the specified <code>String</code> with no attributes. 133: * 134: * @param str The <code>String</code> to be attributed. 135: */ 136: public 137: AttributedString(String str) 138: { 139: sci = new StringCharacterIterator(str); 140: attribs = new AttributeRange[0]; 141: } 142: 143: /*************************************************************************/ 144: 145: /** 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>. 149: * 150: * @param str The <code>String</code> to be attributed. 151: * @param attributes The attribute list. 152: */ 153: public 154: AttributedString(String str, Map attributes) 155: { 156: this(str); 157: 158: attribs = new AttributeRange[1]; 159: attribs[0] = new AttributeRange(attributes, 0, str.length()); 160: } 161: 162: /*************************************************************************/ 163: 164: /** 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>. 168: * 169: * @param aci The <code>AttributedCharacterIterator</code> containing the text and attribute information. 170: */ 171: public 172: AttributedString(AttributedCharacterIterator aci) 173: { 174: this(aci, aci.getBeginIndex(), aci.getEndIndex(), null); 175: } 176: 177: /*************************************************************************/ 178: 179: /** 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>. 183: * 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. 187: */ 188: public 189: AttributedString(AttributedCharacterIterator aci, int begin_index, 190: int end_index) 191: { 192: this(aci, begin_index, end_index, null); 193: } 194: 195: /*************************************************************************/ 196: 197: /** 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 203: * for this object. 204: * 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. 209: */ 210: public 211: AttributedString(AttributedCharacterIterator aci, int begin_index, 212: int end_index, AttributedCharacterIterator.Attribute[] attributes) 213: { 214: // Validate some arguments 215: if ((begin_index < 0) || (end_index < begin_index)) 216: throw new IllegalArgumentException("Bad index values"); 217: 218: StringBuffer sb = new StringBuffer(""); 219: 220: // Get the valid attribute list 221: Set all_attribs = aci.getAllAttributeKeys(); 222: if (attributes != null) 223: all_attribs.retainAll(Arrays.asList(attributes)); 224: 225: // Loop through and extract the attributes 226: char c = aci.setIndex(begin_index); 227: 228: ArrayList accum = new ArrayList(); 229: do 230: { 231: sb.append(c); 232: 233: Iterator iter = all_attribs.iterator(); 234: while(iter.hasNext()) 235: { 236: Object obj = iter.next(); 237: 238: // What should we do if this is not true? 239: if (!(obj instanceof AttributedCharacterIterator.Attribute)) 240: continue; 241: 242: AttributedCharacterIterator.Attribute attrib = 243: (AttributedCharacterIterator.Attribute)obj; 244: 245: // Make sure the attribute is defined. 246: int rl = aci.getRunLimit(attrib); 247: if (rl == -1) 248: continue; 249: if (rl > end_index) 250: rl = end_index; 251: rl -= begin_index; 252: 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)) 256: continue; 257: 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) 262: { 263: if (attrib_obj instanceof Annotation) 264: continue; 265: 266: rs = begin_index; 267: } 268: else 269: { 270: rs -= begin_index; 271: } 272: 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); 276: 277: // Add it to the attribute list. 278: accum.add(new AttributeRange(new_map, rs, rl)); 279: } 280: 281: c = aci.next(); 282: } 283: while(c != CharacterIterator.DONE); 284: 285: attribs = new AttributeRange[accum.size()]; 286: attribs = (AttributeRange[]) accum.toArray(attribs); 287: 288: sci = new StringCharacterIterator(sb.toString()); 289: } 290: 291: /*************************************************************************/ 292: 293: /* 294: * Instance Methods 295: */ 296: 297: /** 298: * This method adds a new attribute that will cover the entire string. 299: * 300: * @param attrib The attribute to add. 301: * @param value The value of the attribute. 302: */ 303: public void 304: addAttribute(AttributedCharacterIterator.Attribute attrib, Object value) 305: { 306: addAttribute(attrib, value, 0, sci.getEndIndex()); 307: } 308: 309: /*************************************************************************/ 310: 311: /** 312: * This method adds a new attribute that will cover the specified subrange 313: * of the string. 314: * 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. 319: * 320: * @exception IllegalArgumentException If attribute is <code>null</code> or the subrange is not valid. 321: */ 322: public void 323: addAttribute(AttributedCharacterIterator.Attribute attrib, Object value, 324: int begin_index, int end_index) 325: { 326: if (attrib == null) 327: throw new IllegalArgumentException("null attribute"); 328: 329: HashMap hm = new HashMap(); 330: hm.put(attrib, value); 331: 332: addAttributes(hm, begin_index, end_index); 333: } 334: 335: /*************************************************************************/ 336: 337: /** 338: * This method adds all of the attributes in the specified list to the 339: * specified subrange of the string. 340: * 341: * @param attributes The list of attributes. 342: * @param begin_index The beginning index. 343: * @param end_index The ending index 344: * 345: * @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid. 346: */ 347: public void 348: addAttributes(Map attributes, int begin_index, int end_index) 349: { 350: if (attributes == null) 351: throw new IllegalArgumentException("null attribute"); 352: 353: if ((begin_index < 0) || (end_index > sci.getEndIndex()) || 354: (end_index < begin_index)) 355: throw new IllegalArgumentException("bad range"); 356: 357: AttributeRange[] new_list = new AttributeRange[attribs.length + 1]; 358: System.arraycopy(attribs, 0, new_list, 0, attribs.length); 359: attribs = new_list; 360: attribs[attribs.length - 1] = new AttributeRange(attributes, begin_index, 361: end_index); 362: } 363: 364: /*************************************************************************/ 365: 366: /** 367: * This method returns an <code>AttributedCharacterIterator</code> that 368: * will iterate over the entire string. 369: * 370: * @return An <code>AttributedCharacterIterator</code> for the entire string. 371: */ 372: public AttributedCharacterIterator 373: getIterator() 374: { 375: return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex(), null)); 376: } 377: 378: /*************************************************************************/ 379: 380: /** 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. 386: * 387: * @param attributes A list of attributes to include in the returned iterator. 388: * 389: * @return An <code>AttributedCharacterIterator</code> for this string. 390: */ 391: public AttributedCharacterIterator 392: getIterator(AttributedCharacterIterator.Attribute[] attributes) 393: { 394: return(getIterator(attributes, 0, sci.getEndIndex())); 395: } 396: 397: /*************************************************************************/ 398: 399: /** 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. 405: * 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. 409: * 410: * @return An <code>AttributedCharacterIterator</code> for this string. 411: */ 412: public AttributedCharacterIterator 413: getIterator(AttributedCharacterIterator.Attribute[] attributes, 414: int begin_index, int end_index) 415: { 416: if ((begin_index < 0) || (end_index > sci.getEndIndex()) || 417: (end_index < begin_index)) 418: throw new IllegalArgumentException("bad range"); 419: 420: return(new AttributedStringIterator(sci, attribs, begin_index, end_index, 421: attributes)); 422: } 423: 424: } // class AttributedString
GNU Classpath (0.17) |