18
18
*/
19
19
20
20
/*
21
- * Copyright (c) 2005, 2021 , Oracle and/or its affiliates. All rights reserved.
21
+ * Copyright (c) 2005, 2023 , Oracle and/or its affiliates. All rights reserved.
22
22
* Portions Copyright (c) 2017, 2020, Chris Fraire <[email protected] >.
23
23
*/
24
24
package org .opengrok .indexer .search .context ;
34
34
import java .util .logging .Logger ;
35
35
36
36
import org .apache .lucene .search .Query ;
37
+ import org .jetbrains .annotations .Nullable ;
38
+ import org .jetbrains .annotations .VisibleForTesting ;
37
39
import org .opengrok .indexer .history .History ;
38
40
import org .opengrok .indexer .history .HistoryEntry ;
39
41
import org .opengrok .indexer .history .HistoryException ;
@@ -119,32 +121,75 @@ public boolean getContext(File src, String path, Writer out, String context) thr
119
121
return getHistoryContext (hist , path , out , null , context );
120
122
}
121
123
124
+ private int matchLine (String line , String urlPrefix , String path , @ Nullable Writer out , @ Nullable List <Hit > hits ,
125
+ String rev , String nrev ) throws IOException {
126
+
127
+ int matchedLines = 0 ;
128
+ tokens .reInit (line );
129
+ String token ;
130
+ int matchState ;
131
+ long start = -1 ;
132
+ while ((token = tokens .next ()) != null ) {
133
+ for (LineMatcher lineMatcher : m ) {
134
+ matchState = lineMatcher .match (token );
135
+ if (matchState == LineMatcher .MATCHED ) {
136
+ if (start < 0 ) {
137
+ start = tokens .getMatchStart ();
138
+ }
139
+ long end = tokens .getMatchEnd ();
140
+ if (start > Integer .MAX_VALUE || end > Integer .MAX_VALUE ) {
141
+ LOGGER .log (Level .WARNING , "Unexpected out of bounds for {0}" , path );
142
+ } else if (hits != null ) {
143
+ StringBuilder sb = new StringBuilder ();
144
+ writeMatch (sb , line , (int ) start , (int ) end ,
145
+ true , path , urlPrefix , nrev , rev );
146
+ hits .add (new Hit (path , sb .toString (), "" , false , false ));
147
+ } else {
148
+ writeMatch (out , line , (int ) start , (int ) end ,
149
+ false , path , urlPrefix , nrev , rev );
150
+ }
151
+ matchedLines ++;
152
+ break ;
153
+ } else if (matchState == LineMatcher .WAIT ) {
154
+ if (start < 0 ) {
155
+ start = tokens .getMatchStart ();
156
+ }
157
+ } else {
158
+ start = -1 ;
159
+ }
160
+ }
161
+ }
162
+
163
+ return matchedLines ;
164
+ }
165
+
122
166
/**
123
- * Writes matching History log entries from 'in' to 'out' or to 'hits'.
124
- * @param in the history to fetch entries from
167
+ * Writes matching history log entries to either 'out' or to 'hits'.
168
+ * @param history the history to fetch entries from
125
169
* @param out to write matched context
126
170
* @param path path to the file
127
- * @param hits list of hits
128
- * @param wcontext web context - beginning of url
171
+ * @param hits list of {@link Hit} instances
172
+ * @param urlPrefix URL prefix
173
+ * @return whether there was at least one line that matched
129
174
*/
130
- private boolean getHistoryContext (
131
- History in , String path , Writer out , List <Hit > hits , String wcontext ) {
132
- if (in == null ) {
175
+ @ VisibleForTesting
176
+ boolean getHistoryContext (History history , String path , @ Nullable Writer out , @ Nullable List <Hit > hits ,
177
+ String urlPrefix ) {
178
+ if (history == null ) {
133
179
throw new IllegalArgumentException ("`in' is null" );
134
180
}
135
181
if ((out == null ) == (hits == null )) {
136
182
// There should be exactly one destination for the output. If
137
183
// none or both are specified, it's a bug.
138
- throw new IllegalArgumentException (
139
- "Exactly one of out and hits should be non-null" );
184
+ throw new IllegalArgumentException ("Exactly one of out and hits should be non-null" );
140
185
}
141
186
142
187
if (m == null ) {
143
188
return false ;
144
189
}
145
190
146
191
int matchedLines = 0 ;
147
- Iterator <HistoryEntry > it = in .getHistoryEntries ().iterator ();
192
+ Iterator <HistoryEntry > it = history .getHistoryEntries (). stream (). filter ( HistoryEntry :: isActive ).iterator ();
148
193
try {
149
194
HistoryEntry he ;
150
195
HistoryEntry nhe = null ;
@@ -153,10 +198,11 @@ private boolean getHistoryContext(
153
198
if (nhe == null ) {
154
199
he = it .next ();
155
200
} else {
156
- he = nhe ; //nhe is the lookahead revision
201
+ he = nhe ; // nhe is the lookahead revision
157
202
}
158
203
String line = he .getLine ();
159
204
String rev = he .getRevision ();
205
+
160
206
if (it .hasNext ()) {
161
207
nhe = it .next ();
162
208
} else {
@@ -169,40 +215,7 @@ private boolean getHistoryContext(
169
215
} else {
170
216
nrev = nhe .getRevision ();
171
217
}
172
- tokens .reInit (line );
173
- String token ;
174
- int matchState ;
175
- long start = -1 ;
176
- while ((token = tokens .next ()) != null ) {
177
- for (LineMatcher lineMatcher : m ) {
178
- matchState = lineMatcher .match (token );
179
- if (matchState == LineMatcher .MATCHED ) {
180
- if (start < 0 ) {
181
- start = tokens .getMatchStart ();
182
- }
183
- long end = tokens .getMatchEnd ();
184
- if (start > Integer .MAX_VALUE || end > Integer .MAX_VALUE ) {
185
- LOGGER .log (Level .INFO , "Unexpected out of bounds for {0}" , path );
186
- } else if (out == null ) {
187
- StringBuilder sb = new StringBuilder ();
188
- writeMatch (sb , line , (int ) start , (int ) end ,
189
- true , path , wcontext , nrev , rev );
190
- hits .add (new Hit (path , sb .toString (), "" , false , false ));
191
- } else {
192
- writeMatch (out , line , (int ) start , (int ) end ,
193
- false , path , wcontext , nrev , rev );
194
- }
195
- matchedLines ++;
196
- break ;
197
- } else if (matchState == LineMatcher .WAIT ) {
198
- if (start < 0 ) {
199
- start = tokens .getMatchStart ();
200
- }
201
- } else {
202
- start = -1 ;
203
- }
204
- }
205
- }
218
+ matchedLines += matchLine (line , urlPrefix , path , out , hits , rev , nrev );
206
219
}
207
220
} catch (Exception e ) {
208
221
LOGGER .log (Level .WARNING , "Could not get history context for " + path , e );
@@ -219,24 +232,23 @@ private boolean getHistoryContext(
219
232
* @param end position of the first char after the match
220
233
* @param flatten should multi-line log entries be flattened to a single
221
234
* @param path path to the file
222
- * @param wcontext web context (begin of URL)
235
+ * @param urlPrefix URL prefix
223
236
* @param nrev old revision
224
237
* @param rev current revision
225
- * line? If {@code true}, replace newline with space.
226
238
* @throws IOException IO exception
227
239
*/
228
240
protected static void writeMatch (Appendable out , String line ,
229
241
int start , int end , boolean flatten , String path ,
230
- String wcontext , String nrev , String rev )
242
+ String urlPrefix , String nrev , String rev )
231
243
throws IOException {
232
244
233
245
String prefix = line .substring (0 , start );
234
246
String match = line .substring (start , end );
235
247
String suffix = line .substring (end );
236
248
237
- if (wcontext != null && nrev != null && !wcontext .isEmpty ()) {
249
+ if (urlPrefix != null && nrev != null && !urlPrefix .isEmpty ()) {
238
250
out .append ("<a href=\" " );
239
- printHTML (out , wcontext + Prefix .DIFF_P +
251
+ printHTML (out , urlPrefix + Prefix .DIFF_P +
240
252
Util .uriEncodePath (path ) +
241
253
"?" + QueryParameters .REVISION_2_PARAM_EQ + Util .uriEncodePath (path ) + "@" +
242
254
rev + "&" + QueryParameters .REVISION_1_PARAM_EQ + Util .uriEncodePath (path ) +
0 commit comments