001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Nikolay A. Kuznetsov
020: * @version $Revision: 1.11.2.2 $
021: */package java.util.regex;
022:
023: /**
024: * Special node for ".*" construction.
025: * The main idea here is to find line terminator and try to find the rest of
026: * the construction from this point.
027: *
028: * @author Nikolay A. Kuznetsov
029: * @version $Revision: 1.11.2.2 $
030: */
031: class DotQuantifierSet extends QuantifierSet {
032:
033: AbstractLineTerminator lt;
034:
035: public DotQuantifierSet(AbstractSet innerSet, AbstractSet next,
036: int type, AbstractLineTerminator lt) {
037: super (innerSet, next, type);
038: this .lt = lt;
039: }
040:
041: public int matches(int stringIndex, CharSequence testString,
042: MatchResultImpl matchResult) {
043:
044: int strLength = matchResult.getRightBound();
045:
046: int startSearch = /* testString.toString().indexOf('\n', stringIndex); */
047: findLineTerminator(stringIndex, strLength, testString);
048:
049: if (startSearch < 0) {
050: startSearch = strLength;
051: }
052:
053: if (startSearch <= stringIndex) {
054: return next.matches(stringIndex, testString, matchResult);
055: }
056: return next.findBack(stringIndex, startSearch, testString,
057: matchResult);
058: }
059:
060: public int find(int stringIndex, CharSequence testString,
061: MatchResultImpl matchResult) {
062: // String testStr = testString.toString();
063: int strLength = matchResult.getRightBound();
064: // 1. skip line terminators ???
065: // //
066: // we don't skip line terminators here, but return zero match instead
067: // //
068:
069: // 2. find first occurrence of the searched pattern
070: // //
071: int res = next.find(stringIndex, testString, matchResult);
072:
073: // 3. Check if we have other occurrences till the end of line
074: // (because .* is greedy and we need last one)
075: // //
076: if (res >= 0) {
077: int nextSearch = findLineTerminator(res, strLength,
078: testString);
079: // testStr.indexOf('\n', res);
080: if (nextSearch < 0) {
081: nextSearch = strLength;
082: }
083: nextSearch = next.findBack(res, nextSearch, testString,
084: matchResult);
085: res = (res < nextSearch) ? nextSearch : res;
086: } else {
087: return -1;
088: }
089:
090: // 4. find left boundary of this search
091: // //
092: int leftBound = (res > 0) ? findBackLineTerminator(stringIndex,
093: res - 1, testString)/* testStr.lastIndexOf('\n', res - 1) */
094: : (res == 0) ? 0 : -1;
095: res = (leftBound >= stringIndex) ? ((leftBound < res) ? leftBound + 1
096: : leftBound)
097: : stringIndex;
098:
099: return res;
100: }
101:
102: /*
103: * All line terminators are from Basic Multilingual Pane
104: */
105: private int findLineTerminator(int from, int to,
106: CharSequence testString) {
107: for (int i = from; i < to; i++) {
108: if (lt.isLineTerminator(testString.charAt(i))) {
109: return i;
110: }
111: }
112: return -1;
113: }
114:
115: private int findBackLineTerminator(int from, int to,
116: CharSequence testString) {
117: for (int i = to; i >= from; i--) {
118: if (lt.isLineTerminator(testString.charAt(i))) {
119: return i;
120: }
121: }
122: return -1;
123: }
124:
125: protected String getName() {
126: return "<DotQuant>";
127: }
128: }
|