Source Code Cross Referenced for SearchIterator.java in  » Internationalization-Localization » icu4j » com » ibm » icu » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Internationalization Localization » icu4j » com.ibm.icu.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *******************************************************************************
003:         * Copyright (C) 1996-2004, International Business Machines Corporation and    *
004:         * others. All Rights Reserved.                                                *
005:         *******************************************************************************
006:         */
007:
008:        package com.ibm.icu.text;
009:
010:        import java.text.CharacterIterator;
011:
012:        /**
013:         * <p>SearchIterator is an abstract base class that defines a protocol
014:         * for text searching. Subclasses provide concrete implementations of
015:         * various search algorithms.  A concrete subclass, StringSearch, is
016:         * provided that implements language-sensitive pattern matching based
017:         * on the comparison rules defined in a RuleBasedCollator
018:         * object. Instances of SearchIterator maintain a current position and
019:         * scan over the target text, returning the indices where a match is
020:         * found and the length of each match. Generally, the sequence of forward 
021:         * matches will be equivalent to the sequence of backward matches.One
022:         * case where this statement may not hold is when non-overlapping mode 
023:         * is set on and there are continuous repetitive patterns in the text. 
024:         * Consider the case searching for pattern "aba" in the text 
025:         * "ababababa", setting overlapping mode off will produce forward matches
026:         * at offsets 0, 4. However when a backwards search is done, the
027:         * results will be at offsets 6 and 2.</p>
028:         * 
029:         * <p>If matches searched for have boundary restrictions. BreakIterators 
030:         * can be used to define the valid boundaries of such a match. Once a 
031:         * BreakIterator is set, potential matches will be tested against the
032:         * BreakIterator to determine if the boundaries are valid and that all
033:         * characters in the potential match are equivalent to the pattern 
034:         * searched for. For example, looking for the pattern "fox" in the text
035:         * "foxy fox" will produce match results at offset 0 and 5 with length 3
036:         * if no BreakIterators were set. However if a WordBreakIterator is set,
037:         * the only match that would be found will be at the offset 5. Since,
038:         * the SearchIterator guarantees that if a BreakIterator is set, all its
039:         * matches will match the given pattern exactly, a potential match that 
040:         * passes the BreakIterator might still not produce a valid match. For 
041:         * instance the pattern "e" will not be found in the string 
042:         * "&#92;u00e9" (latin small letter e with acute) if a 
043:         * CharacterBreakIterator is used. Even though "e" is
044:         * a part of the character "&#92;u00e9" and the potential match at
045:         * offset 0 length 1 passes the CharacterBreakIterator test, "&#92;u00e9"
046:         * is not equivalent to "e", hence the SearchIterator rejects the potential
047:         * match. By default, the SearchIterator
048:         * does not impose any boundary restriction on the matches, it will 
049:         * return all results that match the pattern. Illustrating with the 
050:         * above example, "e" will
051:         * be found in the string "&#92;u00e9" if no BreakIterator is
052:         * specified.</p>
053:         * 
054:         * <p>SearchIterator also provides a means to handle overlapping
055:         * matches via the API setOverlapping(boolean). For example, if
056:         * overlapping mode is set, searching for the pattern "abab" in the
057:         * text "ababab" will match at positions 0 and 2, whereas if
058:         * overlapping is not set, SearchIterator will only match at position
059:         * 0. By default, overlapping mode is not set.</p>
060:         * 
061:         * <p>The APIs in SearchIterator are similar to that of other text
062:         * iteration classes such as BreakIterator. Using this class, it is
063:         * easy to scan through text looking for all occurances of a
064:         * match.</p>
065:         * <p>
066:         * Example of use:<br>
067:         * <pre>
068:         * String target = "The quick brown fox jumped over the lazy fox";
069:         * String pattern = "fox";
070:         * SearchIterator iter = new StringSearch(pattern, target);
071:         * for (int pos = iter.first(); pos != SearchIterator.DONE; 
072:         *                                                       pos = iter.next()) {
073:         *     // println matches at offset 16 and 41 with length 3
074:         *     System.out.println("Found match at " + pos + ", length is " 
075:         *                        + iter.getMatchLength());
076:         * }
077:         * target = "ababababa";
078:         * pattern = "aba";
079:         * iter.setTarget(new StringCharacterIterator(pattern));
080:         * iter.setOverlapping(false);
081:         * System.out.println("Overlapping mode set to false");
082:         * System.out.println("Forward matches of pattern " + pattern + " in text "
083:         *                    + text + ": ");
084:         * for (int pos = iter.first(); pos != SearchIterator.DONE; 
085:         *                                                       pos = iter.next()) {
086:         *     // println matches at offset 0 and 4 with length 3
087:         *     System.out.println("offset " + pos + ", length " 
088:         *                        + iter.getMatchLength());
089:         * }
090:         * System.out.println("Backward matches of pattern " + pattern + " in text "
091:         *                    + text + ": ");
092:         * for (int pos = iter.last(); pos != SearchIterator.DONE; 
093:         *                                                    pos = iter.previous()) {
094:         *     // println matches at offset 6 and 2 with length 3
095:         *     System.out.println("offset " + pos + ", length " 
096:         *                        + iter.getMatchLength());
097:         * }
098:         * System.out.println("Overlapping mode set to true");
099:         * System.out.println("Index set to 2");
100:         * iter.setIndex(2);
101:         * iter.setOverlapping(true);
102:         * System.out.println("Forward matches of pattern " + pattern + " in text "
103:         *                    + text + ": ");
104:         * for (int pos = iter.first(); pos != SearchIterator.DONE; 
105:         *                                                       pos = iter.next()) {
106:         *     // println matches at offset 2, 4 and 6 with length 3
107:         *     System.out.println("offset " + pos + ", length " 
108:         *                        + iter.getMatchLength());
109:         * }
110:         * System.out.println("Index set to 2");
111:         * iter.setIndex(2);
112:         * System.out.println("Backward matches of pattern " + pattern + " in text "
113:         *                    + text + ": ");
114:         * for (int pos = iter.last(); pos != SearchIterator.DONE; 
115:         *                                                    pos = iter.previous()) {
116:         *     // println matches at offset 0 with length 3
117:         *     System.out.println("offset " + pos + ", length " 
118:         *                        + iter.getMatchLength());
119:         * }
120:         * </pre>
121:         * </p>
122:         * @author Laura Werner, synwee
123:         * @stable ICU 2.0
124:         * @see BreakIterator
125:         */
126:        public abstract class SearchIterator {
127:
128:            // public data members -------------------------------------------------
129:
130:            /**
131:             * DONE is returned by previous() and next() after all valid matches have 
132:             * been returned, and by first() and last() if there are no matches at all.
133:             * @see #previous
134:             * @see #next
135:             * @stable ICU 2.0
136:             */
137:            public static final int DONE = -1;
138:
139:            // public methods -----------------------------------------------------
140:
141:            // public setters -----------------------------------------------------
142:
143:            /**
144:             * <p>
145:             * Sets the position in the target text at which the next search will start.
146:             * This method clears any previous match.
147:             * </p>
148:             * @param position position from which to start the next search
149:             * @exception IndexOutOfBoundsException thrown if argument position is out
150:             *            of the target text range.
151:             * @see #getIndex
152:             * @stable ICU 2.8
153:             */
154:            public void setIndex(int position) {
155:                if (position < targetText.getBeginIndex()
156:                        || position > targetText.getEndIndex()) {
157:                    throw new IndexOutOfBoundsException(
158:                            "setIndex(int) expected position to be between "
159:                                    + targetText.getBeginIndex() + " and "
160:                                    + targetText.getEndIndex());
161:                }
162:                m_setOffset_ = position;
163:                m_reset_ = false;
164:                matchLength = 0;
165:            }
166:
167:            /**
168:             * <p>
169:             * Determines whether overlapping matches are returned. See the class 
170:             * documentation for more information about overlapping matches.
171:             * </p>
172:             * <p>
173:             * The default setting of this property is false
174:             * </p>
175:             * @param allowOverlap flag indicator if overlapping matches are allowed
176:             * @see #isOverlapping
177:             * @stable ICU 2.8
178:             */
179:            public void setOverlapping(boolean allowOverlap) {
180:                m_isOverlap_ = allowOverlap;
181:            }
182:
183:            /**
184:             * Set the BreakIterator that is used to restrict the points at which 
185:             * matches are detected.
186:             * Using <tt>null</tt> as the parameter is legal; it means that break 
187:             * detection should not be attempted.
188:             * See class documentation for more information.
189:             * @param breakiter A BreakIterator that will be used to restrict the 
190:             *                     points at which matches are detected.
191:             * @see #getBreakIterator
192:             * @see BreakIterator
193:             * @stable ICU 2.0
194:             */
195:            public void setBreakIterator(BreakIterator breakiter) {
196:                breakIterator = breakiter;
197:                if (breakIterator != null) {
198:                    breakIterator.setText(targetText);
199:                }
200:            }
201:
202:            /**
203:             * Set the target text to be searched. Text iteration will then begin at 
204:             * the start of the text string. This method is useful if you want to 
205:             * reuse an iterator to search within a different body of text.
206:             * @param text new text iterator to look for match, 
207:             * @exception IllegalArgumentException thrown when text is null or has
208:             *               0 length
209:             * @see #getTarget
210:             * @stable ICU 2.4
211:             */
212:            public void setTarget(CharacterIterator text) {
213:                if (text == null || text.getEndIndex() == text.getIndex()) {
214:                    throw new IllegalArgumentException(
215:                            "Illegal null or empty text");
216:                }
217:
218:                targetText = text;
219:                targetText.setIndex(targetText.getBeginIndex());
220:                matchLength = 0;
221:                m_reset_ = true;
222:                m_isForwardSearching_ = true;
223:                if (breakIterator != null) {
224:                    breakIterator.setText(targetText);
225:                }
226:            }
227:
228:            // public getters ----------------------------------------------------
229:
230:            /**
231:             * <p>
232:             * Returns the index of the most recent match in the target text.
233:             * This call returns a valid result only after a successful call to 
234:             * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}.
235:             * Just after construction, or after a searching method returns 
236:             * <tt>DONE</tt>, this method will return <tt>DONE</tt>.
237:             * </p>
238:             * <p>
239:             * Use <tt>getMatchLength</tt> to get the length of the matched text.
240:             * <tt>getMatchedText</tt> will return the subtext in the searched 
241:             * target text from index getMatchStart() with length getMatchLength(). 
242:             * </p>
243:             * @return index to a substring within the text string that is being 
244:             *         searched.
245:             * @see #getMatchLength
246:             * @see #getMatchedText
247:             * @see #first
248:             * @see #next
249:             * @see #previous
250:             * @see #last
251:             * @see #DONE
252:             * @stable ICU 2.8
253:             */
254:            public int getMatchStart() {
255:                return m_lastMatchStart_;
256:            }
257:
258:            /**
259:             * Return the index in the target text at which the iterator is currently
260:             * positioned. 
261:             * If the iteration has gone past the end of the target text, or past 
262:             * the beginning for a backwards search, {@link #DONE} is returned.
263:             * @return index in the target text at which the iterator is currently 
264:             *         positioned.
265:             * @stable ICU 2.8
266:             * @see #first
267:             * @see #next
268:             * @see #previous
269:             * @see #last
270:             * @see #DONE
271:             */
272:            public abstract int getIndex();
273:
274:            /**
275:             * <p>
276:             * Returns the length of the most recent match in the target text. 
277:             * This call returns a valid result only after a successful
278:             * call to {@link #first}, {@link #next}, {@link #previous}, or 
279:             * {@link #last}.
280:             * Just after construction, or after a searching method returns
281:             * <tt>DONE</tt>, this method will return 0. See getMatchStart() for 
282:             * more details.
283:             * </p>
284:             * @return The length of the most recent match in the target text, or 0 if 
285:             *         there is no match.
286:             * @see #getMatchStart
287:             * @see #getMatchedText
288:             * @see #first
289:             * @see #next
290:             * @see #previous
291:             * @see #last
292:             * @see #DONE
293:             * @stable ICU 2.0
294:             */
295:            public int getMatchLength() {
296:                return matchLength;
297:            }
298:
299:            /**
300:             * Returns the BreakIterator that is used to restrict the indexes at which 
301:             * matches are detected. This will be the same object that was passed to 
302:             * the constructor or to <code>setBreakIterator</code>.
303:             * If the BreakIterator has not been set, <tt>null</tt> will be returned.
304:             * See setBreakIterator for more information.
305:             * @return the BreakIterator set to restrict logic matches
306:             * @see #setBreakIterator
307:             * @see BreakIterator
308:             * @stable ICU 2.0
309:             */
310:            public BreakIterator getBreakIterator() {
311:                return breakIterator;
312:            }
313:
314:            /**
315:             * Return the target text that is being searched.
316:             * @return target text being searched.
317:             * @see #setTarget
318:             * @stable ICU 2.0
319:             */
320:            public CharacterIterator getTarget() {
321:                return targetText;
322:            }
323:
324:            /**
325:             * Returns the text that was matched by the most recent call to 
326:             * {@link #first}, {@link #next}, {@link #previous}, or {@link #last}. 
327:             * If the iterator is not pointing at a valid match, for instance just 
328:             * after construction or after <tt>DONE</tt> has been returned, an empty 
329:             * String will be returned. See getMatchStart for more information
330:             * @see #getMatchStart
331:             * @see #getMatchLength
332:             * @see #first
333:             * @see #next
334:             * @see #previous
335:             * @see #last
336:             * @see #DONE
337:             * @return the substring in the target text of the most recent match 
338:             * @stable ICU 2.0
339:             */
340:            public String getMatchedText() {
341:                if (matchLength > 0) {
342:                    int limit = m_lastMatchStart_ + matchLength;
343:                    StringBuffer result = new StringBuffer(matchLength);
344:                    result.append(targetText.current());
345:                    targetText.next();
346:                    while (targetText.getIndex() < limit) {
347:                        result.append(targetText.current());
348:                        targetText.next();
349:                    }
350:                    targetText.setIndex(m_lastMatchStart_);
351:                    return result.toString();
352:                }
353:                return null;
354:            }
355:
356:            // miscellaneous public methods -----------------------------------------
357:
358:            /**
359:             * Search <b>forwards</b> in the target text for the next valid match,
360:             * starting the search from the current iterator position. The iterator is 
361:             * adjusted so that its current index, as returned by {@link #getIndex},
362:             * is the starting position of the match if one was found. If a match is 
363:             * found, the index of the match is returned, otherwise <tt>DONE</tt> is
364:             * returned.  If overlapping mode is set, the beginning of the found match
365:             * can be before the end of the current match, if any.
366:             * @return The starting index of the next forward match after the current 
367:             *         iterator position, or 
368:             *         <tt>DONE</tt> if there are no more matches.
369:             * @see #getMatchStart
370:             * @see #getMatchLength
371:             * @see #getMatchedText
372:             * @see #following
373:             * @see #preceding
374:             * @see #previous
375:             * @see #first
376:             * @see #last
377:             * @see #DONE
378:             * @stable ICU 2.0
379:             */
380:            public int next() {
381:                int start = targetText.getIndex();
382:                if (m_setOffset_ != DONE) {
383:                    start = m_setOffset_;
384:                    m_setOffset_ = DONE;
385:                }
386:                if (m_isForwardSearching_) {
387:                    if (!m_reset_
388:                            && start + matchLength >= targetText.getEndIndex()) {
389:                        // not enough characters to match
390:                        matchLength = 0;
391:                        targetText.setIndex(targetText.getEndIndex());
392:                        m_lastMatchStart_ = DONE;
393:                        return DONE;
394:                    }
395:                    m_reset_ = false;
396:                } else {
397:                    // switching direction. 
398:                    // if matchedIndex == USEARCH_DONE, it means that either a 
399:                    // setIndex has been called or that previous ran off the text
400:                    // string. the iterator would have been set to offset 0 if a 
401:                    // match is not found.
402:                    m_isForwardSearching_ = true;
403:                    if (start != DONE) {
404:                        // there's no need to set the collation element iterator
405:                        // the next call to next will set the offset.
406:                        return start;
407:                    }
408:                }
409:
410:                if (start == DONE) {
411:                    start = targetText.getBeginIndex();
412:                }
413:                if (matchLength > 0) {
414:                    // if match length is 0 we are at the start of the iteration
415:                    if (m_isOverlap_) {
416:                        start++;
417:                    } else {
418:                        start += matchLength;
419:                    }
420:                }
421:                m_lastMatchStart_ = handleNext(start);
422:                return m_lastMatchStart_;
423:            }
424:
425:            /**
426:             * Search <b>backwards</b> in the target text for the next valid match,
427:             * starting the search from the current iterator position. The iterator is 
428:             * adjusted so that its current index, as returned by {@link #getIndex},
429:             * is the starting position of the match if one was found. If a match is 
430:             * found, the index is returned, otherwise <tt>DONE</tt> is returned.  If
431:             * overlapping mode is set, the end of the found match can be after the
432:             * beginning of the previous match, if any.
433:             * @return The starting index of the next backwards match after the current 
434:             *         iterator position, or 
435:             *         <tt>DONE</tt> if there are no more matches.
436:             * @see #getMatchStart
437:             * @see #getMatchLength
438:             * @see #getMatchedText
439:             * @see #following
440:             * @see #preceding
441:             * @see #next
442:             * @see #first
443:             * @see #last
444:             * @see #DONE
445:             * @stable ICU 2.0
446:             */
447:            public int previous() {
448:                int start = targetText.getIndex();
449:                if (m_setOffset_ != DONE) {
450:                    start = m_setOffset_;
451:                    m_setOffset_ = DONE;
452:                }
453:                if (m_reset_) {
454:                    m_isForwardSearching_ = false;
455:                    m_reset_ = false;
456:                    start = targetText.getEndIndex();
457:                }
458:
459:                if (m_isForwardSearching_ == true) {
460:                    // switching direction. 
461:                    // if matchedIndex == USEARCH_DONE, it means that either a 
462:                    // setIndex has been called or that next ran off the text
463:                    // string. the iterator would have been set to offset textLength if 
464:                    // a match is not found.
465:                    m_isForwardSearching_ = false;
466:                    if (start != targetText.getEndIndex()) {
467:                        return start;
468:                    }
469:                } else {
470:                    if (start == targetText.getBeginIndex()) {
471:                        // not enough characters to match
472:                        matchLength = 0;
473:                        targetText.setIndex(targetText.getBeginIndex());
474:                        m_lastMatchStart_ = DONE;
475:                        return DONE;
476:                    }
477:                }
478:
479:                m_lastMatchStart_ = handlePrevious(start);
480:                return m_lastMatchStart_;
481:            }
482:
483:            /**
484:             * Return true if the overlapping property has been set.
485:             * See setOverlapping(boolean) for more information.
486:             * @see #setOverlapping
487:             * @return true if the overlapping property has been set, false otherwise
488:             * @stable ICU 2.8
489:             */
490:            public boolean isOverlapping() {
491:                return m_isOverlap_;
492:            }
493:
494:            /** 
495:             * <p>
496:             * Resets the search iteration. All properties will be reset to their
497:             * default values.
498:             * </p>
499:             * <p>
500:             * If a forward iteration is initiated, the next search will begin at the
501:             * start of the target text. Otherwise, if a backwards iteration is initiated,
502:             * the next search will begin at the end of the target text.
503:             * </p>
504:             * @stable ICU 2.8
505:             */
506:            public void reset() {
507:                // reset is setting the attributes that are already in string search
508:                matchLength = 0;
509:                setIndex(targetText.getBeginIndex());
510:                m_isOverlap_ = false;
511:                m_isForwardSearching_ = true;
512:                m_reset_ = true;
513:                m_setOffset_ = DONE;
514:            }
515:
516:            /**
517:             * Return the index of the first <b>forward</b> match in the target text. 
518:             * This method sets the iteration to begin at the start of the 
519:             * target text and searches forward from there.
520:             * @return The index of the first forward match, or <code>DONE</code> 
521:             *            if there are no matches.
522:             * @see #getMatchStart
523:             * @see #getMatchLength
524:             * @see #getMatchedText
525:             * @see #following
526:             * @see #preceding
527:             * @see #next
528:             * @see #previous
529:             * @see #last
530:             * @see #DONE
531:             * @stable ICU 2.0
532:             */
533:            public final int first() {
534:                m_isForwardSearching_ = true;
535:                setIndex(targetText.getBeginIndex());
536:                return next();
537:            }
538:
539:            /**
540:             * Return the index of the first <b>forward</b> match in target text that 
541:             * is at or after argument <tt>position</tt>. 
542:             * This method sets the iteration to begin at the specified
543:             * position in the the target text and searches forward from there.
544:             * @return The index of the first forward match, or <code>DONE</code> 
545:             *         if there are no matches.
546:             * @see #getMatchStart
547:             * @see #getMatchLength
548:             * @see #getMatchedText
549:             * @see #first
550:             * @see #preceding
551:             * @see #next
552:             * @see #previous
553:             * @see #last
554:             * @see #DONE
555:             * @stable ICU 2.0
556:             */
557:            public final int following(int position) {
558:                m_isForwardSearching_ = true;
559:                // position checked in usearch_setOffset
560:                setIndex(position);
561:                return next();
562:            }
563:
564:            /**
565:             * Return the index of the first <b>backward</b> match in target text. 
566:             * This method sets the iteration to begin at the end of the 
567:             * target text and searches backwards from there.
568:             * @return The starting index of the first backward match, or 
569:             *         <code>DONE</code> if there are no matches.
570:             * @see #getMatchStart
571:             * @see #getMatchLength
572:             * @see #getMatchedText
573:             * @see #first
574:             * @see #preceding
575:             * @see #next
576:             * @see #previous
577:             * @see #following
578:             * @see #DONE
579:             * @stable ICU 2.0
580:             */
581:            public final int last() {
582:                m_isForwardSearching_ = false;
583:                setIndex(targetText.getEndIndex());
584:                return previous();
585:            }
586:
587:            /**
588:             * Return the index of the first <b>backwards</b> match in target 
589:             * text that ends at or before argument <tt>position</tt>. 
590:             * This method sets the iteration to begin at the argument
591:             * position index of the target text and searches backwards from there.
592:             * @return The starting index of the first backwards match, or 
593:             *         <code>DONE</code> 
594:             *         if there are no matches.
595:             * @see #getMatchStart
596:             * @see #getMatchLength
597:             * @see #getMatchedText
598:             * @see #first
599:             * @see #following
600:             * @see #next
601:             * @see #previous
602:             * @see #last
603:             * @see #DONE
604:             * @stable ICU 2.0
605:             */
606:            public final int preceding(int position) {
607:                m_isForwardSearching_ = false;
608:                // position checked in usearch_setOffset
609:                setIndex(position);
610:                return previous();
611:            }
612:
613:            // protected data member ----------------------------------------------
614:
615:            /**
616:             * The BreakIterator to define the boundaries of a logical match.
617:             * This value can be a null.
618:             * See class documentation for more information.
619:             * @see #setBreakIterator(BreakIterator)
620:             * @see #getBreakIterator
621:             * @see BreakIterator
622:             * @stable ICU 2.0
623:             */
624:            protected BreakIterator breakIterator;
625:
626:            /**
627:             * Target text for searching.
628:             * @see #setTarget(CharacterIterator)
629:             * @see #getTarget
630:             * @stable ICU 2.0
631:             */
632:            protected CharacterIterator targetText;
633:            /**
634:             * Length of the most current match in target text. 
635:             * Value 0 is the default value.
636:             * @see #setMatchLength
637:             * @see #getMatchLength
638:             * @stable ICU 2.0
639:             */
640:            protected int matchLength;
641:
642:            // protected constructor ----------------------------------------------
643:
644:            /**
645:             * Protected constructor for use by subclasses.
646:             * Initializes the iterator with the argument target text for searching 
647:             * and sets the BreakIterator.
648:             * See class documentation for more details on the use of the target text
649:             * and BreakIterator.
650:             * @param target The target text to be searched.
651:             * @param breaker A {@link BreakIterator} that is used to determine the 
652:             *                boundaries of a logical match. This argument can be null.
653:             * @exception IllegalArgumentException thrown when argument target is null,
654:             *            or of length 0
655:             * @see BreakIterator  
656:             * @stable ICU 2.0
657:             */
658:            protected SearchIterator(CharacterIterator target,
659:                    BreakIterator breaker) {
660:                if (target == null
661:                        || (target.getEndIndex() - target.getBeginIndex()) == 0) {
662:                    throw new IllegalArgumentException(
663:                            "Illegal argument target. "
664:                                    + " Argument can not be null or of length 0");
665:                }
666:                targetText = target;
667:                breakIterator = breaker;
668:                if (breakIterator != null) {
669:                    breakIterator.setText(target);
670:                }
671:                matchLength = 0;
672:                m_lastMatchStart_ = DONE;
673:                m_isOverlap_ = false;
674:                m_isForwardSearching_ = true;
675:                m_reset_ = true;
676:                m_setOffset_ = DONE;
677:            }
678:
679:            // protected methods --------------------------------------------------
680:
681:            /**
682:             * Sets the length of the most recent match in the target text. 
683:             * Subclasses' handleNext() and handlePrevious() methods should call this 
684:             * after they find a match in the target text.    
685:             * @param length new length to set
686:             * @see #handleNext
687:             * @see #handlePrevious
688:             * @stable ICU 2.0
689:             */
690:            protected void setMatchLength(int length) {
691:                matchLength = length;
692:            }
693:
694:            /**
695:             * <p>
696:             * Abstract method that subclasses override to provide the mechanism 
697:             * for finding the next <b>forwards</b> match in the target text. This 
698:             * allows different subclasses to provide different search algorithms.
699:             * </p> 
700:             * <p>
701:             * If a match is found, this function must call setMatchLength(int) to
702:             * set the length of the result match.
703:             * The iterator is adjusted so that its current index, as returned by 
704:             * {@link #getIndex}, is the starting position of the match if one was 
705:             * found. If a match is not found, <tt>DONE</tt> will be returned.
706:             * </p> 
707:             * @param start index in the target text at which the forwards search 
708:             *        should begin.
709:             * @return the starting index of the next forwards match if found, DONE 
710:             *         otherwise
711:             * @see #setMatchLength(int)
712:             * @see #handlePrevious(int)
713:             * @see #DONE
714:             * @stable ICU 2.0
715:             */
716:            protected abstract int handleNext(int start);
717:
718:            /**
719:             * <p>
720:             * Abstract method which subclasses override to provide the mechanism 
721:             * for finding the next <b>backwards</b> match in the target text. 
722:             * This allows different 
723:             * subclasses to provide different search algorithms. 
724:             * </p> 
725:             * <p>
726:             * If a match is found, this function must call setMatchLength(int) to
727:             * set the length of the result match.
728:             * The iterator is adjusted so that its current index, as returned by 
729:             * {@link #getIndex}, is the starting position of the match if one was 
730:             * found. If a match is not found, <tt>DONE</tt> will be returned.
731:             * </p> 
732:             * @param startAt index in the target text at which the backwards search 
733:             *        should begin.
734:             * @return the starting index of the next backwards match if found, 
735:             *         DONE otherwise
736:             * @see #setMatchLength(int)
737:             * @see #handleNext(int)
738:             * @see #DONE
739:             * @stable ICU 2.0
740:             */
741:            protected abstract int handlePrevious(int startAt);
742:
743:            // private data members ------------------------------------------------
744:
745:            /**
746:             * Flag indicates if we are doing a forwards search
747:             */
748:            private boolean m_isForwardSearching_;
749:            /**
750:             * Flag to indicate if overlapping search is to be done.
751:             * E.g. looking for "aa" in "aaa" will yield matches at offset 0 and 1.
752:             */
753:            private boolean m_isOverlap_;
754:            /**
755:             * Flag indicates if we are at the start of a string search.
756:             * This indicates that we are in forward search and at the start of m_text.
757:             */
758:            private boolean m_reset_;
759:            /**
760:             * Data member to store user defined position in setIndex().
761:             * If setIndex() is not called, this value will be DONE.
762:             */
763:            private int m_setOffset_;
764:            /**
765:             * Offset of the beginning of the last match
766:             */
767:            private int m_lastMatchStart_;
768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.