File Source: IRCDocumentSearcher.java
/*
P/P * Method: com.dmdirc.addons.ui_swing.textpane.IRCDocumentSearcher__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 package com.dmdirc.addons.ui_swing.textpane;
24
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29
30 /**
31 * Searches the textpane for specified phrases.
32 */
33 public class IRCDocumentSearcher {
34
35 /** Document to search. */
36 private final IRCDocument document;
37
38 /** Phrase to search for. */
39 private final String phrase;
40
41 /** Textpane position. */
42 private LinePosition position;
43
44 /** Case sensitive? */
45 private final boolean caseSensitive;
46
47 /**
48 * Constructs a new IRC Document searcher.
49 *
50 * @param phrase Phrase to search for
51 * @param document Document to search
52 * @param caseSensitive Whether or not this searcher is case sensitive
53 */
54 public IRCDocumentSearcher(final String phrase, final IRCDocument document,
/*
P/P * Method: void com.dmdirc.addons.ui_swing.textpane.IRCDocumentSearcher(String, IRCDocument, bool)
*
* Preconditions:
* document != null
* document.lines != null
*
* Presumptions:
* java.util.List:size(...)@78 in {-231+1..232-1}
*
* Postconditions:
* this.caseSensitive == caseSensitive
* init'ed(this.caseSensitive)
* this.document == document
* this.document != null
* this.phrase == phrase
* init'ed(this.phrase)
* this.position == &new LinePosition(getEndPosition#1)
* new LinePosition(getEndPosition#1) num objects == 1
* new LinePosition(getEndPosition#1).endLine <= 232-2
* new LinePosition(getEndPosition#1).startLine == new LinePosition(getEndPosition#1).endLine
* ...
*/
55 final boolean caseSensitive) {
56 this.phrase = phrase;
57 this.document = document;
58 this.position = getEndPosition();
59 this.caseSensitive = caseSensitive;
60 }
61
62 /**
63 * Returns the end position in the document.
64 *
65 * @return End position
66 */
67 private LinePosition getEndPosition() {
/*
P/P * Method: LinePosition getEndPosition()
*
* Preconditions:
* this.document != null
* this.document.lines != null
*
* Presumptions:
* getLine(...).lineParts != null
* getLine(...).lineParts.length <= 232-1
* getLine(...).lineParts[...] != null
* java.util.List:get(...)@89 != null
* java.util.List:size(...)@78 >= -231+1
* ...
*
* Postconditions:
* return_value == &new LinePosition(getEndPosition#1)
* new LinePosition(getEndPosition#1) num objects == 1
* return_value.endLine <= 232-2
* return_value.startLine == return_value.endLine
* init'ed(return_value.endPos)
* return_value.startPos == return_value.endPos
*
* Test Vectors:
* java.util.List:size(...)@78: {-231+1..0}, {1..232-1}
*/
68 final int documentSize = document.getNumLines() - 1;
69 final int lineLength;
70 if (documentSize >= 0) {
71 lineLength = document.getLine(documentSize).getLength();
72 } else {
73 lineLength = 0;
74 }
75
76 return new LinePosition(documentSize, lineLength, documentSize,
77 lineLength);
78 }
79
80 /**
81 * Sets the position of the current match
82 *
83 * @param position New match position
84 */
85 public void setPosition(final LinePosition position) {
/*
P/P * Method: void setPosition(LinePosition)
*
* Postconditions:
* this.position == position
* init'ed(this.position)
*/
86 this.position = position;
87 }
88
89 /**
90 * Searches up in the document.
91 *
92 * @return Line position of the next match
93 */
94 public LinePosition searchUp() {
/*
P/P * Method: LinePosition searchUp()
*
* Preconditions:
* init'ed(this.position)
* this.document != null
* this.document.lines != null
* (soft) init'ed(this.position.endLine)
* (soft) init'ed(this.position.endPos)
*
* Presumptions:
* getEndPosition(...)@96 init'ed
* getLine(...).lineParts.length <= 232-1
* java.util.List:get(...)@109 != null
* java.util.List:get(...)@89 != null
* java.util.List:size(...)@108 >= -231+1
* ...
*
* Postconditions:
* init'ed(return_value)
* this.position == One-of{old this.position, &new LinePosition(getEndPosition#1)}
* this.position != null
* new LinePosition(getEndPosition#1) num objects <= 1
* new LinePosition(getEndPosition#1).endLine <= 232-2
* init'ed(new LinePosition(getEndPosition#1).endPos)
* new LinePosition(getEndPosition#1).startLine <= 232-2
* init'ed(new LinePosition(getEndPosition#1).startPos)
*
* Test Vectors:
* this.position: Inverse{null}, Addr_Set{null}
*/
95 if (position == null) {
96 position = getEndPosition();
97 }
98
99 int line = position.getEndLine();
100 for (int remaining = document.getNumLines(); remaining > 0; remaining--) {
101 if (line < 0) {
102 line = 0;
103 }
104 final String lineText = document.getLine(line).getText();
105
106 final List<LinePosition> matches = searchLine(line, lineText);
107
108 for (int i = matches.size() - 1; i >= 0; i--) {
109 if (position.getEndLine() != line
110 || matches.get(i).getEndPos() < position.getEndPos()) {
111 return matches.get(i);
112 }
113 }
114
115 line--;
116
117 if (line < 0) {
118 line += document.getNumLines();
119 }
120
121 }
122
123 return null;
124 }
125
126 /**
127 * Searches down in the document.
128 *
129 * @return Line position of the next match
130 */
131 public LinePosition searchDown() {
/*
P/P * Method: LinePosition searchDown()
*
* Preconditions:
* init'ed(this.position)
* this.document != null
* this.document.lines != null
* (soft) init'ed(this.position.startLine)
* (soft) init'ed(this.position.startPos)
*
* Presumptions:
* line - java.util.List:size(...)@78 in {-231-1..232-2, 6_442_450_943}
* getEndPosition(...)@133 init'ed
* getLine(...).lineParts.length <= 232-1
* java.util.Iterator:next(...)@145 != null
* java.util.List:get(...)@89 != null
*
* Postconditions:
* init'ed(return_value)
* this.position == One-of{old this.position, &new LinePosition(getEndPosition#1)}
* this.position != null
* new LinePosition(getEndPosition#1) num objects <= 1
* new LinePosition(getEndPosition#1).endLine <= 232-2
* init'ed(new LinePosition(getEndPosition#1).endPos)
* new LinePosition(getEndPosition#1).startLine <= 232-2
* init'ed(new LinePosition(getEndPosition#1).startPos)
*
* Test Vectors:
* this.position: Inverse{null}, Addr_Set{null}
* java.util.Iterator:hasNext(...)@145: {0}, {1}
*/
132 if (position == null) {
133 position = getEndPosition();
134 }
135
136 int line = position.getStartLine();
137 for (int remaining = document.getNumLines(); remaining > 0; remaining--) {
138 if (line < 0) {
139 line = 0;
140 }
141 final String lineText = document.getLine(line).getText();
142
143 final List<LinePosition> matches = searchLine(line, lineText);
144
145 for (LinePosition match : matches) {
146 if (position.getStartLine() != line
147 || match.getStartPos() > position.getStartPos()) {
148 return match;
149 }
150 }
151
152 line++;
153
154 if (line >= document.getNumLines()) {
155 line -= document.getNumLines();
156 }
157 }
158
159 return null;
160 }
161
162 /**
163 * Searches a line and returns all matches on a line.
164 *
165 * @param lineNum the line number of the line we're searching
166 * @param line Line to search
167 * @return List of matches
168 */
169 private List<LinePosition> searchLine(final int lineNum, final String line) {
/*
P/P * Method: List searchLine(int, String)
*
* Presumptions:
* java.util.regex.Pattern:compile(...)@171 != null
* java.util.regex.Pattern:matcher(...)@171 != null
*
* Postconditions:
* return_value == &new ArrayList(searchLine#1)
* new ArrayList(searchLine#1) num objects == 1
*
* Test Vectors:
* java.util.regex.Matcher:find(...)@174: {0}, {1}
*/
170 final List<LinePosition> matches = new ArrayList<LinePosition>();
171 final Matcher matcher = Pattern.compile((caseSensitive ? "" : "(?i)") +
172 "\\Q" + phrase + "\\E").matcher(line);
173
174 while (matcher.find()) {
175 matches.add(new LinePosition(lineNum, matcher.start(), lineNum, matcher.end()));
176 }
177
178 return matches;
179 }
180
181 }
SofCheck Inspector Build Version : 2.17854
| IRCDocumentSearcher.java |
2009-Jun-25 01:54:24 |
| IRCDocumentSearcher.class |
2009-Sep-02 17:04:16 |