KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > text > CollationElementIterator


1 /*
2  * @(#)CollationElementIterator.java 1.48 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /*
9  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
10  * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
11  *
12  * The original version of this source code and documentation is copyrighted
13  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
14  * materials are provided under terms of a License Agreement between Taligent
15  * and Sun. This technology is protected by multiple US and International
16  * patents. This notice and attribution to Taligent may not be removed.
17  * Taligent is a registered trademark of Taligent, Inc.
18  *
19  */

20
21 package java.text;
22
23 import java.lang.Character JavaDoc;
24 import java.util.Vector JavaDoc;
25 import sun.text.Normalizer;
26 import sun.text.NormalizerUtilities;
27
28 /**
29  * The <code>CollationElementIterator</code> class is used as an iterator
30  * to walk through each character of an international string. Use the iterator
31  * to return the ordering priority of the positioned character. The ordering
32  * priority of a character, which we refer to as a key, defines how a character
33  * is collated in the given collation object.
34  *
35  * <p>
36  * For example, consider the following in Spanish:
37  * <blockquote>
38  * <pre>
39  * "ca" -> the first key is key('c') and second key is key('a').
40  * "cha" -> the first key is key('ch') and second key is key('a').
41  * </pre>
42  * </blockquote>
43  * And in German,
44  * <blockquote>
45  * <pre>
46  * "äb"-> the first key is key('a'), the second key is key('e'), and
47  * the third key is key('b').
48  * </pre>
49  * </blockquote>
50  * The key of a character is an integer composed of primary order(short),
51  * secondary order(byte), and tertiary order(byte). Java strictly defines
52  * the size and signedness of its primitive data types. Therefore, the static
53  * functions <code>primaryOrder</code>, <code>secondaryOrder</code>, and
54  * <code>tertiaryOrder</code> return <code>int</code>, <code>short</code>,
55  * and <code>short</code> respectively to ensure the correctness of the key
56  * value.
57  *
58  * <p>
59  * Example of the iterator usage,
60  * <blockquote>
61  * <pre>
62  *
63  * String testString = "This is a test";
64  * RuleBasedCollator ruleBasedCollator = (RuleBasedCollator)Collator.getInstance();
65  * CollationElementIterator collationElementIterator = ruleBasedCollator.getCollationElementIterator(testString);
66  * int primaryOrder = CollationElementIterator.primaryOrder(collationElementIterator.next());
67  * </pre>
68  * </blockquote>
69  *
70  * <p>
71  * <code>CollationElementIterator.next</code> returns the collation order
72  * of the next character. A collation order consists of primary order,
73  * secondary order and tertiary order. The data type of the collation
74  * order is <strong>int</strong>. The first 16 bits of a collation order
75  * is its primary order; the next 8 bits is the secondary order and the
76  * last 8 bits is the tertiary order.
77  *
78  * @see Collator
79  * @see RuleBasedCollator
80  * @version 1.24 07/27/98
81  * @author Helena Shih, Laura Werner, Richard Gillam
82  */

83 public final class CollationElementIterator
84 {
85     /**
86      * Null order which indicates the end of string is reached by the
87      * cursor.
88      */

89     public final static int NULLORDER = 0xffffffff;
90
91     /**
92      * CollationElementIterator constructor. This takes the source string and
93      * the collation object. The cursor will walk thru the source string based
94      * on the predefined collation rules. If the source string is empty,
95      * NULLORDER will be returned on the calls to next().
96      * @param sourceText the source string.
97      * @param order the collation object.
98      */

99     CollationElementIterator(String JavaDoc sourceText, RuleBasedCollator JavaDoc owner) {
100         this.owner = owner;
101         ordering = owner.getTables();
102         if ( sourceText.length() != 0 ) {
103             Normalizer.Mode JavaDoc mode =
104                 NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
105             text = new Normalizer JavaDoc(sourceText, mode);
106         }
107     }
108
109     /**
110      * CollationElementIterator constructor. This takes the source string and
111      * the collation object. The cursor will walk thru the source string based
112      * on the predefined collation rules. If the source string is empty,
113      * NULLORDER will be returned on the calls to next().
114      * @param sourceText the source string.
115      * @param order the collation object.
116      */

117     CollationElementIterator(CharacterIterator JavaDoc sourceText, RuleBasedCollator JavaDoc owner) {
118         this.owner = owner;
119         ordering = owner.getTables();
120         Normalizer.Mode JavaDoc mode =
121             NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
122         text = new Normalizer JavaDoc(sourceText, mode);
123     }
124     /**
125      * Resets the cursor to the beginning of the string. The next call
126      * to next() will return the first collation element in the string.
127      */

128     public void reset()
129     {
130         if (text != null) {
131             text.reset();
132             Normalizer.Mode JavaDoc mode =
133                 NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
134             text.setMode(mode);
135         }
136         buffer = null;
137         expIndex = 0;
138         swapOrder = 0;
139     }
140
141     /**
142      * Get the next collation element in the string. <p>This iterator iterates
143      * over a sequence of collation elements that were built from the string.
144      * Because there isn't necessarily a one-to-one mapping from characters to
145      * collation elements, this doesn't mean the same thing as "return the
146      * collation element [or ordering priority] of the next character in the
147      * string".</p>
148      * <p>This function returns the collation element that the iterator is currently
149      * pointing to and then updates the internal pointer to point to the next element.
150      * previous() updates the pointer first and then returns the element. This
151      * means that when you change direction while iterating (i.e., call next() and
152      * then call previous(), or call previous() and then call next()), you'll get
153      * back the same element twice.</p>
154      */

155     public int next()
156     {
157         if (text == null) {
158             return NULLORDER;
159         }
160         Normalizer.Mode JavaDoc textMode = text.getMode();
161         // convert the owner's mode to something the Normalizer understands
162
Normalizer.Mode JavaDoc ownerMode =
163         NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
164         if (textMode != ownerMode) {
165             text.setMode(ownerMode);
166         }
167
168         // if buffer contains any decomposed char values
169
// return their strength orders before continuing in
170
// the the Normalizer's CharacterIterator.
171
if (buffer != null) {
172             if (expIndex < buffer.length) {
173                 return strengthOrder(buffer[expIndex++]);
174             } else {
175                 buffer = null;
176                 expIndex = 0;
177             }
178         } else if (swapOrder != 0) {
179             if (Character.isSupplementaryCodePoint(swapOrder)) {
180                 char[] chars = Character.toChars(swapOrder);
181                 swapOrder = chars[1];
182                 return chars[0] << 16;
183             }
184             int order = swapOrder << 16;
185             swapOrder = 0;
186             return order;
187         }
188         int ch = text.next();
189
190         // are we at the end of Normalizer's text?
191
if (ch == Normalizer.DONE) {
192             return NULLORDER;
193         }
194
195         int value = ordering.getUnicodeOrder(ch);
196         if (value == RuleBasedCollator.UNMAPPED) {
197             swapOrder = ch;
198             return UNMAPPEDCHARVALUE;
199         }
200         else if (value >= RuleBasedCollator.CONTRACTCHARINDEX) {
201             value = nextContractChar(ch);
202         }
203         if (value >= RuleBasedCollator.EXPANDCHARINDEX) {
204             buffer = ordering.getExpandValueList(value);
205             expIndex = 0;
206             value = buffer[expIndex++];
207         }
208
209         if (ordering.isSEAsianSwapping()) {
210             int consonant;
211             if (isThaiPreVowel(ch)) {
212             consonant = text.next();
213                 if (isThaiBaseConsonant(consonant)) {
214                     buffer = makeReorderedBuffer(consonant, value, buffer, true);
215                     value = buffer[0];
216                     expIndex = 1;
217                 } else {
218                     text.previous();
219                 }
220             }
221             if (isLaoPreVowel(ch)) {
222             consonant = text.next();
223                 if (isLaoBaseConsonant(consonant)) {
224                     buffer = makeReorderedBuffer(consonant, value, buffer, true);
225                     value = buffer[0];
226                     expIndex = 1;
227                 } else {
228                     text.previous();
229                 }
230             }
231         }
232
233         return strengthOrder(value);
234     }
235
236     /**
237      * Get the previous collation element in the string. <p>This iterator iterates
238      * over a sequence of collation elements that were built from the string.
239      * Because there isn't necessarily a one-to-one mapping from characters to
240      * collation elements, this doesn't mean the same thing as "return the
241      * collation element [or ordering priority] of the previous character in the
242      * string".</p>
243      * <p>This function updates the iterator's internal pointer to point to the
244      * collation element preceding the one it's currently pointing to and then
245      * returns that element, while next() returns the current element and then
246      * updates the pointer. This means that when you change direction while
247      * iterating (i.e., call next() and then call previous(), or call previous()
248      * and then call next()), you'll get back the same element twice.</p>
249      * @since 1.2
250      */

251     public int previous()
252     {
253         if (text == null) {
254             return NULLORDER;
255         }
256         Normalizer.Mode JavaDoc textMode = text.getMode();
257         // convert the owner's mode to something the Normalizer understands
258
Normalizer.Mode JavaDoc ownerMode =
259         NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
260         if (textMode != ownerMode) {
261             text.setMode(ownerMode);
262         }
263         if (buffer != null) {
264             if (expIndex > 0) {
265                 return strengthOrder(buffer[--expIndex]);
266             } else {
267                 buffer = null;
268                 expIndex = 0;
269             }
270         } else if (swapOrder != 0) {
271             if (Character.isSupplementaryCodePoint(swapOrder)) {
272                 char[] chars = Character.toChars(swapOrder);
273                 swapOrder = chars[1];
274                 return chars[0] << 16;
275             }
276             int order = swapOrder << 16;
277             swapOrder = 0;
278             return order;
279         }
280         int ch = text.previous();
281         if (ch == Normalizer.DONE) {
282             return NULLORDER;
283         }
284
285         int value = ordering.getUnicodeOrder(ch);
286
287         if (value == RuleBasedCollator.UNMAPPED) {
288             swapOrder = UNMAPPEDCHARVALUE;
289             return ch;
290         } else if (value >= RuleBasedCollator.CONTRACTCHARINDEX) {
291             value = prevContractChar(ch);
292         }
293         if (value >= RuleBasedCollator.EXPANDCHARINDEX) {
294             buffer = ordering.getExpandValueList(value);
295             expIndex = buffer.length;
296             value = buffer[--expIndex];
297         }
298
299         if (ordering.isSEAsianSwapping()) {
300             int vowel;
301             if (isThaiBaseConsonant(ch)) {
302                 vowel = text.previous();
303                 if (isThaiPreVowel(vowel)) {
304                     buffer = makeReorderedBuffer(vowel, value, buffer, false);
305                     expIndex = buffer.length - 1;
306                     value = buffer[expIndex];
307                 } else {
308                     text.next();
309                 }
310             }
311             if (isLaoBaseConsonant(ch)) {
312             vowel = text.previous();
313                 if (isLaoPreVowel(vowel)) {
314                     buffer = makeReorderedBuffer(vowel, value, buffer, false);
315                     expIndex = buffer.length - 1;
316                     value = buffer[expIndex];
317                 } else {
318                     text.next();
319                 }
320             }
321         }
322
323         return strengthOrder(value);
324     }
325
326     /**
327      * Return the primary component of a collation element.
328      * @param order the collation element
329      * @return the element's primary component
330      */

331     public final static int primaryOrder(int order)
332     {
333         order &= RBCollationTables.PRIMARYORDERMASK;
334         return (order >>> RBCollationTables.PRIMARYORDERSHIFT);
335     }
336     /**
337      * Return the secondary component of a collation element.
338      * @param order the collation element
339      * @return the element's secondary component
340      */

341     public final static short secondaryOrder(int order)
342     {
343         order = order & RBCollationTables.SECONDARYORDERMASK;
344         return ((short)(order >> RBCollationTables.SECONDARYORDERSHIFT));
345     }
346     /**
347      * Return the tertiary component of a collation element.
348      * @param order the collation element
349      * @return the element's tertiary component
350      */

351     public final static short tertiaryOrder(int order)
352     {
353         return ((short)(order &= RBCollationTables.TERTIARYORDERMASK));
354     }
355
356     /**
357      * Get the comparison order in the desired strength. Ignore the other
358      * differences.
359      * @param order The order value
360      */

361     final int strengthOrder(int order)
362     {
363         int s = owner.getStrength();
364         if (s == Collator.PRIMARY)
365         {
366             order &= RBCollationTables.PRIMARYDIFFERENCEONLY;
367         } else if (s == Collator.SECONDARY)
368         {
369             order &= RBCollationTables.SECONDARYDIFFERENCEONLY;
370         }
371         return order;
372     }
373
374     /**
375      * Sets the iterator to point to the collation element corresponding to
376      * the specified character (the parameter is a CHARACTER offset in the
377      * original string, not an offset into its corresponding sequence of
378      * collation elements). The value returned by the next call to next()
379      * will be the collation element corresponding to the specified position
380      * in the text. If that position is in the middle of a contracting
381      * character sequence, the result of the next call to next() is the
382      * collation element for that sequence. This means that getOffset()
383      * is not guaranteed to return the same value as was passed to a preceding
384      * call to setOffset().
385      *
386      * @param newOffset The new character offset into the original text.
387      * @since 1.2
388      */

389     public void setOffset(int newOffset)
390     {
391         if (text != null) {
392             if (newOffset < text.getBeginIndex()
393                 || newOffset >= text.getEndIndex()) {
394                     text.setIndexOnly(newOffset);
395             } else {
396                 int c = text.setIndex(newOffset);
397
398                 // if the desired character isn't used in a contracting character
399
// sequence, bypass all the backing-up logic-- we're sitting on
400
// the right character already
401
if (ordering.usedInContractSeq(c)) {
402                     // walk backwards through the string until we see a character
403
// that DOESN'T participate in a contracting character sequence
404
while (ordering.usedInContractSeq(c)) {
405                 c = text.previous();
406                     }
407                     // now walk forward using this object's next() method until
408
// we pass the starting point and set our current position
409
// to the beginning of the last "character" before or at
410
// our starting position
411
int last = text.getIndex();
412                     while (text.getIndex() <= newOffset) {
413                         last = text.getIndex();
414                         next();
415                     }
416                     text.setIndexOnly(last);
417             // we don't need this, since last is the last index
418
// that is the starting of the contraction which encompass
419
// newOffset
420
// text.previous();
421
}
422             }
423         }
424         buffer = null;
425         expIndex = 0;
426         swapOrder = 0;
427     }
428
429     /**
430      * Returns the character offset in the original text corresponding to the next
431      * collation element. (That is, getOffset() returns the position in the text
432      * corresponding to the collation element that will be returned by the next
433      * call to next().) This value will always be the index of the FIRST character
434      * corresponding to the collation element (a contracting character sequence is
435      * when two or more characters all correspond to the same collation element).
436      * This means if you do setOffset(x) followed immediately by getOffset(), getOffset()
437      * won't necessarily return x.
438      *
439      * @return The character offset in the original text corresponding to the collation
440      * element that will be returned by the next call to next().
441      * @since 1.2
442      */

443     public int getOffset()
444     {
445         return (text != null) ? text.getIndex() : 0;
446     }
447
448
449     /**
450      * Return the maximum length of any expansion sequences that end
451      * with the specified comparison order.
452      * @param order a collation order returned by previous or next.
453      * @return the maximum length of any expansion sequences ending
454      * with the specified order.
455      * @since 1.2
456      */

457     public int getMaxExpansion(int order)
458     {
459         return ordering.getMaxExpansion(order);
460     }
461
462     /**
463      * Set a new string over which to iterate.
464      *
465      * @param source the new source text
466      * @since 1.2
467      */

468     public void setText(String JavaDoc source)
469     {
470         buffer = null;
471         swapOrder = 0;
472         expIndex = 0;
473         Normalizer.Mode JavaDoc mode =
474             NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
475         if (text == null) {
476             text = new Normalizer JavaDoc(source, mode);
477         } else {
478             text.setMode(mode);
479             text.setText(source);
480         }
481     }
482
483     /**
484      * Set a new string over which to iterate.
485      *
486      * @param source the new source text.
487      * @since 1.2
488      */

489     public void setText(CharacterIterator JavaDoc source)
490     {
491         buffer = null;
492         swapOrder = 0;
493         expIndex = 0;
494         Normalizer.Mode JavaDoc mode =
495             NormalizerUtilities.toNormalizerMode(owner.getDecomposition());
496         if (text == null) {
497             text = new Normalizer JavaDoc(source, mode);
498         } else {
499             text.setMode(mode);
500             text.setText(source);
501         }
502     }
503
504     //============================================================
505
// privates
506
//============================================================
507

508     /**
509      * Determine if a character is a Thai vowel (which sorts after
510      * its base consonant).
511      */

512     private final static boolean isThaiPreVowel(int ch) {
513         return (ch >= 0x0e40) && (ch <= 0x0e44);
514     }
515
516     /**
517      * Determine if a character is a Thai base consonant
518      */

519     private final static boolean isThaiBaseConsonant(int ch) {
520         return (ch >= 0x0e01) && (ch <= 0x0e2e);
521     }
522
523     /**
524      * Determine if a character is a Lao vowel (which sorts after
525      * its base consonant).
526      */

527     private final static boolean isLaoPreVowel(int ch) {
528         return (ch >= 0x0ec0) && (ch <= 0x0ec4);
529     }
530
531     /**
532      * Determine if a character is a Lao base consonant
533      */

534     private final static boolean isLaoBaseConsonant(int ch) {
535         return (ch >= 0x0e81) && (ch <= 0x0eae);
536     }
537
538     /**
539      * This method produces a buffer which contains the collation
540      * elements for the two characters, with colFirst's values preceding
541      * another character's. Presumably, the other character precedes colFirst
542      * in logical order (otherwise you wouldn't need this method would you?).
543      * The assumption is that the other char's value(s) have already been
544      * computed. If this char has a single element it is passed to this
545      * method as lastValue, and lastExpansion is null. If it has an
546      * expansion it is passed in lastExpansion, and colLastValue is ignored.
547      */

548     private int[] makeReorderedBuffer(int colFirst,
549                                       int lastValue,
550                                       int[] lastExpansion,
551                                       boolean forward) {
552
553         int[] result;
554
555         int firstValue = ordering.getUnicodeOrder(colFirst);
556         if (firstValue >= RuleBasedCollator.CONTRACTCHARINDEX) {
557             firstValue = forward? nextContractChar(colFirst) : prevContractChar(colFirst);
558         }
559
560         int[] firstExpansion = null;
561         if (firstValue >= RuleBasedCollator.EXPANDCHARINDEX) {
562             firstExpansion = ordering.getExpandValueList(firstValue);
563         }
564
565         if (!forward) {
566             int temp1 = firstValue;
567             firstValue = lastValue;
568             lastValue = temp1;
569             int[] temp2 = firstExpansion;
570             firstExpansion = lastExpansion;
571             lastExpansion = temp2;
572         }
573
574         if (firstExpansion == null && lastExpansion == null) {
575             result = new int [2];
576             result[0] = firstValue;
577             result[1] = lastValue;
578         }
579         else {
580             int firstLength = firstExpansion==null? 1 : firstExpansion.length;
581             int lastLength = lastExpansion==null? 1 : lastExpansion.length;
582             result = new int[firstLength + lastLength];
583
584             if (firstExpansion == null) {
585                 result[0] = firstValue;
586             }
587             else {
588                 System.arraycopy(firstExpansion, 0, result, 0, firstLength);
589             }
590
591             if (lastExpansion == null) {
592                 result[firstLength] = lastValue;
593             }
594             else {
595                 System.arraycopy(lastExpansion, 0, result, firstLength, lastLength);
596             }
597         }
598
599         return result;
600     }
601
602     /**
603      * Check if a comparison order is ignorable.
604      * @return true if a character is ignorable, false otherwise.
605      */

606     final static boolean isIgnorable(int order)
607     {
608         return ((primaryOrder(order) == 0) ? true : false);
609     }
610
611     /**
612      * Get the ordering priority of the next contracting character in the
613      * string.
614      * @param ch the starting character of a contracting character token
615      * @return the next contracting character's ordering. Returns NULLORDER
616      * if the end of string is reached.
617      */

618     private int nextContractChar(int ch)
619     {
620         // First get the ordering of this single character,
621
// which is always the first element in the list
622
Vector JavaDoc list = ordering.getContractValues(ch);
623         EntryPair JavaDoc pair = (EntryPair JavaDoc)list.firstElement();
624         int order = pair.value;
625
626         // find out the length of the longest contracting character sequence in the list.
627
// There's logic in the builder code to make sure the longest sequence is always
628
// the last.
629
pair = (EntryPair JavaDoc)list.lastElement();
630         int maxLength = pair.entryName.length();
631
632         // (the Normalizer is cloned here so that the seeking we do in the next loop
633
// won't affect our real position in the text)
634
Normalizer JavaDoc tempText = (Normalizer JavaDoc)text.clone();
635
636         // extract the next maxLength characters in the string (we have to do this using the
637
// Normalizer to ensure that our offsets correspond to those the rest of the
638
// iterator is using) and store it in "fragment".
639
tempText.previous();
640         key.setLength(0);
641         int c = tempText.next();
642         while (maxLength > 0 && c != Normalizer.DONE) {
643             if (Character.isSupplementaryCodePoint(c)) {
644                 key.append(Character.toChars(c));
645                 maxLength -= 2;
646             } else {
647                 key.append((char)c);
648                 --maxLength;
649             }
650             c = tempText.next();
651         }
652         String JavaDoc fragment = key.toString();
653         // now that we have that fragment, iterate through this list looking for the
654
// longest sequence that matches the characters in the actual text. (maxLength
655
// is used here to keep track of the length of the longest sequence)
656
// Upon exit from this loop, maxLength will contain the length of the matching
657
// sequence and order will contain the collation-element value corresponding
658
// to this sequence
659
maxLength = 1;
660         for (int i = list.size() - 1; i > 0; i--) {
661             pair = (EntryPair JavaDoc)list.elementAt(i);
662             if (!pair.fwd)
663                 continue;
664
665             if (fragment.startsWith(pair.entryName) && pair.entryName.length()
666                     > maxLength) {
667                 maxLength = pair.entryName.length();
668                 order = pair.value;
669             }
670         }
671
672         // seek our current iteration position to the end of the matching sequence
673
// and return the appropriate collation-element value (if there was no matching
674
// sequence, we're already seeked to the right position and order already contains
675
// the correct collation-element value for the single character)
676
while (maxLength > 1) {
677             c = text.next();
678             maxLength -= Character.charCount(c);
679         }
680         return order;
681     }
682
683     /**
684      * Get the ordering priority of the previous contracting character in the
685      * string.
686      * @param ch the starting character of a contracting character token
687      * @return the next contracting character's ordering. Returns NULLORDER
688      * if the end of string is reached.
689      */

690     private int prevContractChar(int ch)
691     {
692         // This function is identical to nextContractChar(), except that we've
693
// switched things so that the next() and previous() calls on the Normalizer
694
// are switched and so that we skip entry pairs with the fwd flag turned on
695
// rather than off. Notice that we still use append() and startsWith() when
696
// working on the fragment. This is because the entry pairs that are used
697
// in reverse iteration have their names reversed already.
698
Vector JavaDoc list = ordering.getContractValues(ch);
699         EntryPair JavaDoc pair = (EntryPair JavaDoc)list.firstElement();
700         int order = pair.value;
701
702         pair = (EntryPair JavaDoc)list.lastElement();
703         int maxLength = pair.entryName.length();
704
705         Normalizer JavaDoc tempText = (Normalizer JavaDoc)text.clone();
706
707         tempText.next();
708         key.setLength(0);
709         int c = tempText.previous();
710         while (maxLength > 0 && c != Normalizer.DONE) {
711             if (Character.isSupplementaryCodePoint(c)) {
712                 key.append(Character.toChars(c));
713                 maxLength -= 2;
714             } else {
715                 key.append((char)c);
716                 --maxLength;
717             }
718             c = tempText.previous();
719         }
720         String JavaDoc fragment = key.toString();
721
722         maxLength = 1;
723         for (int i = list.size() - 1; i > 0; i--) {
724             pair = (EntryPair JavaDoc)list.elementAt(i);
725             if (pair.fwd)
726                 continue;
727
728             if (fragment.startsWith(pair.entryName) && pair.entryName.length()
729                     > maxLength) {
730                 maxLength = pair.entryName.length();
731                 order = pair.value;
732             }
733         }
734
735         while (maxLength > 1) {
736             c = text.previous();
737             maxLength -= Character.charCount(c);
738         }
739         return order;
740     }
741
742     final static int UNMAPPEDCHARVALUE = 0x7FFF0000;
743
744     private Normalizer JavaDoc text = null;
745     private int[] buffer = null;
746     private int expIndex = 0;
747     private StringBuffer JavaDoc key = new StringBuffer JavaDoc(5);
748     private int swapOrder = 0;
749     private RBCollationTables JavaDoc ordering;
750     private RuleBasedCollator JavaDoc owner;
751 }
752
Popular Tags