pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / analyzers / common / src / java / org / apache / lucene / analysis / util / CharArrayIterator.java
1 package org.apache.lucene.analysis.util;
2
3 import java.text.BreakIterator; // javadoc
4 import java.text.CharacterIterator;
5 import java.util.Locale;
6
7 /** 
8  * A CharacterIterator used internally for use with {@link BreakIterator}
9  * @lucene.internal
10  */
11 public abstract class CharArrayIterator implements CharacterIterator {
12   private char array[];
13   private int start;
14   private int index;
15   private int length;
16   private int limit;
17
18   public char [] getText() {
19     return array;
20   }
21   
22   public int getStart() {
23     return start;
24   }
25   
26   public int getLength() {
27     return length;
28   }
29   
30   /**
31    * Set a new region of text to be examined by this iterator
32    * 
33    * @param array text buffer to examine
34    * @param start offset into buffer
35    * @param length maximum length to examine
36    */
37   public void setText(final char array[], int start, int length) {
38     this.array = array;
39     this.start = start;
40     this.index = start;
41     this.length = length;
42     this.limit = start + length;
43   }
44
45   public char current() {
46     return (index == limit) ? DONE : jreBugWorkaround(array[index]);
47   }
48   
49   protected abstract char jreBugWorkaround(char ch);
50
51   public char first() {
52     index = start;
53     return current();
54   }
55
56   public int getBeginIndex() {
57     return 0;
58   }
59
60   public int getEndIndex() {
61     return length;
62   }
63
64   public int getIndex() {
65     return index - start;
66   }
67
68   public char last() {
69     index = (limit == start) ? limit : limit - 1;
70     return current();
71   }
72
73   public char next() {
74     if (++index >= limit) {
75       index = limit;
76       return DONE;
77     } else {
78       return current();
79     }
80   }
81
82   public char previous() {
83     if (--index < start) {
84       index = start;
85       return DONE;
86     } else {
87       return current();
88     }
89   }
90
91   public char setIndex(int position) {
92     if (position < getBeginIndex() || position > getEndIndex())
93       throw new IllegalArgumentException("Illegal Position: " + position);
94     index = start + position;
95     return current();
96   }
97   
98   @Override
99   public Object clone() {
100     try {
101       return super.clone();
102     } catch (CloneNotSupportedException e) {
103       // CharacterIterator does not allow you to throw CloneNotSupported
104       throw new RuntimeException(e);
105     }
106   }
107   
108   /**
109    * Create a new CharArrayIterator that works around JRE bugs
110    * in a manner suitable for {@link BreakIterator#getSentenceInstance()}
111    */
112   public static CharArrayIterator newSentenceInstance() {
113     if (HAS_BUGGY_BREAKITERATORS) {
114       return new CharArrayIterator() {
115         // work around this for now by lying about all surrogates to 
116         // the sentence tokenizer, instead we treat them all as 
117         // SContinue so we won't break around them.
118         @Override
119         protected char jreBugWorkaround(char ch) {
120           return ch >= 0xD800 && ch <= 0xDFFF ? 0x002C : ch;
121         }
122       };
123     } else {
124       return new CharArrayIterator() {
125         // no bugs
126         @Override
127         protected char jreBugWorkaround(char ch) {
128           return ch;
129         }
130       };
131     }
132   }
133   
134   /**
135    * Create a new CharArrayIterator that works around JRE bugs
136    * in a manner suitable for {@link BreakIterator#getWordInstance()}
137    */
138   public static CharArrayIterator newWordInstance() {
139     if (HAS_BUGGY_BREAKITERATORS) {
140       return new CharArrayIterator() {
141         // work around this for now by lying about all surrogates to the word, 
142         // instead we treat them all as ALetter so we won't break around them.
143         @Override
144         protected char jreBugWorkaround(char ch) {
145           return ch >= 0xD800 && ch <= 0xDFFF ? 0x0041 : ch;
146         }
147       };
148     } else {
149       return new CharArrayIterator() {
150         // no bugs
151         @Override
152         protected char jreBugWorkaround(char ch) {
153           return ch;
154         }
155       };
156     }
157   }
158   
159   /**
160    * True if this JRE has a buggy BreakIterator implementation
161    */
162   public static final boolean HAS_BUGGY_BREAKITERATORS;
163   static {
164     boolean v;
165     try {
166       BreakIterator bi = BreakIterator.getSentenceInstance(Locale.US);
167       bi.setText("\udb40\udc53");
168       bi.next();
169       v = false;
170     } catch (Exception e) {
171       v = true;
172     }
173     HAS_BUGGY_BREAKITERATORS = v;
174   }
175 }