Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 package java.text;
     26 
     27 import java.util.ArrayList;
     28 
     29 /**
     30  * CharacterIteratorFieldDelegate combines the notifications from a Format
     31  * into a resulting <code>AttributedCharacterIterator</code>. The resulting
     32  * <code>AttributedCharacterIterator</code> can be retrieved by way of
     33  * the <code>getIterator</code> method.
     34  *
     35  */
     36 class CharacterIteratorFieldDelegate implements Format.FieldDelegate {
     37     /**
     38      * Array of AttributeStrings. Whenever <code>formatted</code> is invoked
     39      * for a region > size, a new instance of AttributedString is added to
     40      * attributedStrings. Subsequent invocations of <code>formatted</code>
     41      * for existing regions result in invoking addAttribute on the existing
     42      * AttributedStrings.
     43      */
     44     private ArrayList<AttributedString> attributedStrings;
     45     /**
     46      * Running count of the number of characters that have
     47      * been encountered.
     48      */
     49     private int size;
     50 
     51 
     52     CharacterIteratorFieldDelegate() {
     53         attributedStrings = new ArrayList<>();
     54     }
     55 
     56     public void formatted(Format.Field attr, Object value, int start, int end,
     57                           StringBuffer buffer) {
     58         if (start != end) {
     59             if (start < size) {
     60                 // Adjust attributes of existing runs
     61                 int index = size;
     62                 int asIndex = attributedStrings.size() - 1;
     63 
     64                 while (start < index) {
     65                     AttributedString as = attributedStrings.
     66                                            get(asIndex--);
     67                     int newIndex = index - as.length();
     68                     int aStart = Math.max(0, start - newIndex);
     69 
     70                     as.addAttribute(attr, value, aStart, Math.min(
     71                                     end - start, as.length() - aStart) +
     72                                     aStart);
     73                     index = newIndex;
     74                 }
     75             }
     76             if (size < start) {
     77                 // Pad attributes
     78                 attributedStrings.add(new AttributedString(
     79                                           buffer.substring(size, start)));
     80                 size = start;
     81             }
     82             if (size < end) {
     83                 // Add new string
     84                 int aStart = Math.max(start, size);
     85                 AttributedString string = new AttributedString(
     86                                    buffer.substring(aStart, end));
     87 
     88                 string.addAttribute(attr, value);
     89                 attributedStrings.add(string);
     90                 size = end;
     91             }
     92         }
     93     }
     94 
     95     public void formatted(int fieldID, Format.Field attr, Object value,
     96                           int start, int end, StringBuffer buffer) {
     97         formatted(attr, value, start, end, buffer);
     98     }
     99 
    100     /**
    101      * Returns an <code>AttributedCharacterIterator</code> that can be used
    102      * to iterate over the resulting formatted String.
    103      *
    104      * @pararm string Result of formatting.
    105      */
    106     public AttributedCharacterIterator getIterator(String string) {
    107         // Add the last AttributedCharacterIterator if necessary
    108         // assert(size <= string.length());
    109         if (string.length() > size) {
    110             attributedStrings.add(new AttributedString(
    111                                   string.substring(size)));
    112             size = string.length();
    113         }
    114         int iCount = attributedStrings.size();
    115         AttributedCharacterIterator iterators[] = new
    116                                     AttributedCharacterIterator[iCount];
    117 
    118         for (int counter = 0; counter < iCount; counter++) {
    119             iterators[counter] = attributedStrings.
    120                                   get(counter).getIterator();
    121         }
    122         return new AttributedString(iterators).getIterator();
    123     }
    124 }
    125