123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391 |
- /* AttributedStringIterator.java -- Class to iterate over AttributedString
- Copyright (C) 1998, 1999, 2004, 2005, 2006, 2012 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., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 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.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Map;
- import java.util.Set;
- import static java.text.AttributedCharacterIterator.Attribute;
- /**
- * This class implements the AttributedCharacterIterator interface. It
- * is used by AttributedString.getIterator().
- *
- * @version 0.0
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
- class AttributedStringIterator implements AttributedCharacterIterator
- {
- /*************************************************************************/
- /** The character iterator containing the text */
- private CharacterIterator ci;
- /** The list of attributes and ranges */
- private AttributedString.AttributeRange[] attribs;
- /**
- * The list of attributes that the user is interested in. We may,
- * at our option, not return any other attributes.
- */
- private Attribute[] restricts;
- /*************************************************************************/
- /**
- * Creates a new instance.
- *
- * @param sci an iterator for the string content.
- * @param attribs the attribute ranges.
- * @param beginIndex the start index.
- * @param endIndex the end index.
- * @param restricts the attributes that the user is interested in.
- */
- AttributedStringIterator(StringCharacterIterator sci,
- AttributedString.AttributeRange[] attribs,
- int beginIndex, int endIndex,
- AttributedCharacterIterator.Attribute[] restricts)
- {
- this.ci = new StringCharacterIterator(sci, beginIndex, endIndex);
- this.attribs = attribs;
- this.restricts = restricts;
- }
- /*************************************************************************/
- // First we have a bunch of stupid redirects. If StringCharacterIterator
- // weren't final, I just would have extended that for this class. Alas, no.
- public Object clone()
- {
- return(ci.clone());
- }
- public char current()
- {
- return(ci.current());
- }
- public char next()
- {
- return(ci.next());
- }
- public char previous()
- {
- return(ci.previous());
- }
- public char first()
- {
- return(ci.first());
- }
- public char last()
- {
- return(ci.last());
- }
- public int getIndex()
- {
- return(ci.getIndex());
- }
- public char setIndex(int index)
- {
- return(ci.setIndex(index));
- }
- public int getBeginIndex()
- {
- return(ci.getBeginIndex());
- }
- public int getEndIndex()
- {
- return(ci.getEndIndex());
- }
- /*
- * Here is where the AttributedCharacterIterator methods start.
- */
- /*************************************************************************/
- /**
- * Returns a list of all the attribute keys that are defined anywhere
- * on this string.
- */
- public Set<Attribute> getAllAttributeKeys()
- {
- HashSet<Attribute> s = new HashSet<Attribute>();
- if (attribs == null)
- return(s);
- for (int i = 0; i < attribs.length; i++)
- {
- if (attribs[i].beginIndex > getEndIndex()
- || attribs[i].endIndex <= getBeginIndex())
- continue;
- Iterator<? extends Attribute> iter = attribs[i].attribs.keySet().iterator();
- while (iter.hasNext())
- {
- s.add(iter.next());
- }
- }
- return(s);
- }
- /*************************************************************************/
- /**
- * Various methods that determine how far the run extends for various
- * attribute combinations.
- */
- public int getRunLimit()
- {
- return getRunLimit(getAllAttributeKeys());
- }
- public int getRunLimit(Attribute attrib)
- {
- HashSet<Attribute> s = new HashSet<Attribute>();
- s.add(attrib);
- return(getRunLimit(s));
- }
- public synchronized int getRunLimit(Set<? extends Attribute> attributeSet)
- {
- if (attributeSet == null)
- return ci.getEndIndex();
- int current = ci.getIndex();
- int end = ci.getEndIndex();
- int limit = current;
- if (current == end)
- return end;
- Map<Attribute,Object> runValues = getAttributes();
- while (limit < end)
- {
- Iterator<? extends Attribute> iterator = attributeSet.iterator();
- while (iterator.hasNext())
- {
- Attribute attributeKey = iterator.next();
- Object v1 = runValues.get(attributeKey);
- Object v2 = getAttribute(attributeKey, limit + 1);
- boolean changed = false;
- // check for equal or both null, if NO return start
- if (v1 != null)
- {
- changed = !v1.equals(v2);
- }
- else
- {
- changed = (v2 != null);
- }
- if (changed)
- return limit + 1;
- }
- // no differences, so increment limit and next and loop again
- limit++;
- }
- return end;
- }
- /*************************************************************************/
- /**
- * Various methods that determine where the run begins for various
- * attribute combinations.
- */
- /**
- * Returns the index of the first character in the run containing the current
- * character and defined by all the attributes defined for that character
- * position.
- *
- * @return The run start index.
- */
- public int getRunStart()
- {
- return(getRunStart(getAttributes().keySet()));
- }
- /**
- * Returns the index of the first character in the run, defined by the
- * specified attribute, that contains the current character.
- *
- * @param attrib the attribute (<code>null</code> permitted).
- *
- * return The index of the first character in the run.
- */
- public int getRunStart(Attribute attrib)
- {
- if (attrib == null)
- return ci.getBeginIndex();
- HashSet<Attribute> s = new HashSet<Attribute>();
- s.add(attrib);
- return(getRunStart(s));
- }
- /**
- * Returns the index of the first character in the run, defined by the
- * specified attribute set, that contains the current character.
- *
- * @param attributeSet the attribute set (<code>null</code> permitted).
- *
- * return The index of the first character in the run.
- */
- public int getRunStart(Set<? extends Attribute> attributeSet)
- {
- if (attributeSet == null)
- return ci.getBeginIndex();
- int current = ci.getIndex();
- int begin = ci.getBeginIndex();
- int start = current;
- if (start == begin)
- return begin;
- Map<Attribute, Object> runValues = getAttributes();
- int prev = start - 1;
- while (start > begin)
- {
- Iterator<? extends Attribute> iterator = attributeSet.iterator();
- while (iterator.hasNext())
- {
- Attribute attributeKey = iterator.next();
- Object v1 = runValues.get(attributeKey);
- Object v2 = getAttribute(attributeKey, prev);
- boolean changed = false;
- // check for equal or both null, if NO return start
- if (v1 != null)
- {
- changed = !v1.equals(v2);
- }
- else
- {
- changed = (v2 != null);
- }
- if (changed)
- return start;
- }
- // no differences, so decrement start and prev and loop again
- start--;
- prev--;
- }
- return start;
- }
- /*************************************************************************/
- /**
- * Returns the value for an attribute at the specified position. If the
- * attribute key (<code>key</code>) is <code>null</code>, the method returns
- * <code>null</code>.
- *
- * @param key the key (<code>null</code> permitted).
- * @param pos the character position.
- *
- * @return The attribute value (possibly <code>null</code>).
- */
- private Object getAttribute(AttributedCharacterIterator.Attribute key,
- int pos)
- {
- if (attribs == null)
- return null;
- for (int i = attribs.length - 1; i >= 0; i--)
- {
- if (pos >= attribs[i].beginIndex && pos < attribs[i].endIndex)
- {
- Set<? extends Attribute> keys = attribs[i].attribs.keySet();
- if (keys.contains(key))
- {
- return attribs[i].attribs.get(key);
- }
- }
- }
- return null;
- }
- /**
- * Returns the value for an attribute at the current position. If the
- * attribute key (<code>key</code>) is <code>null</code>, the method returns
- * <code>null</code>.
- *
- * @param key the key (<code>null</code> permitted).
- *
- * @return The attribute value (possibly <code>null</code>).
- */
- public Object getAttribute(AttributedCharacterIterator.Attribute key)
- {
- return getAttribute(key, ci.getIndex());
- }
- /*************************************************************************/
- /**
- * Return a list of all the attributes and values defined for this
- * character
- */
- public Map<Attribute,Object> getAttributes()
- {
- HashMap<Attribute,Object> m = new HashMap<Attribute,Object>();
- if (attribs == null)
- return(m);
- for (int i = 0; i < attribs.length; i++)
- {
- if ((ci.getIndex() >= attribs[i].beginIndex) &&
- (ci.getIndex() < attribs[i].endIndex))
- m.putAll(attribs[i].attribs);
- }
- return(m);
- }
- } // class AttributedStringIterator
|