41
41
import org .apache .lucene .search .uhighlight .UnifiedHighlighter ;
42
42
import org .apache .lucene .util .BytesRef ;
43
43
import org .apache .lucene .util .automaton .CharacterRunAutomaton ;
44
+ import org .opensolaris .opengrok .analysis .AnalyzerGuru ;
44
45
import org .opensolaris .opengrok .analysis .ExpandTabsReader ;
45
46
import org .opensolaris .opengrok .analysis .StreamSource ;
46
47
import org .opensolaris .opengrok .configuration .RuntimeEnvironment ;
@@ -62,6 +63,8 @@ public class OGKUnifiedHighlighter extends UnifiedHighlighter {
62
63
63
64
private int tabSize ;
64
65
66
+ private String fileTypeName ;
67
+
65
68
/**
66
69
* Initializes an instance with
67
70
* {@link UnifiedHighlighter#UnifiedHighlighter(org.apache.lucene.search.IndexSearcher, org.apache.lucene.analysis.Analyzer)}
@@ -82,6 +85,22 @@ public OGKUnifiedHighlighter(RuntimeEnvironment env,
82
85
this .env = env ;
83
86
}
84
87
88
+ /**
89
+ * Gets a file type name-specific analyzer during the execution of
90
+ * {@link #highlightFieldsUnion(java.lang.String[], org.apache.lucene.search.Query, int, int)},
91
+ * or just gets the object passed in to the constructor at all other times.
92
+ * @return a defined instance
93
+ */
94
+ @ Override
95
+ public Analyzer getIndexAnalyzer () {
96
+ String ftname = fileTypeName ;
97
+ if (ftname == null ) {
98
+ return indexAnalyzer ;
99
+ }
100
+ Analyzer fa = AnalyzerGuru .getAnalyzer (ftname );
101
+ return fa == null ? indexAnalyzer : fa ;
102
+ }
103
+
85
104
public int getTabSize () {
86
105
return tabSize ;
87
106
}
@@ -90,6 +109,34 @@ public void setTabSize(int value) {
90
109
this .tabSize = value ;
91
110
}
92
111
112
+ /**
113
+ * Transiently arranges that {@link #getIndexAnalyzer()} returns a file type
114
+ * name-specific analyzer during a subsequent call of
115
+ * {@link #highlightFieldsUnionWork(java.lang.String[], org.apache.lucene.search.Query, int, int)}.
116
+ * @param fields a defined instance
117
+ * @param query a defined instance
118
+ * @param docId a valid document ID
119
+ * @param lineLimit the maximum number of lines to return
120
+ * @return a defined instance or else {@code null} if there are no results
121
+ * @throws IOException if accessing the Lucene document fails
122
+ */
123
+ public String highlightFieldsUnion (String [] fields , Query query ,
124
+ int docId , int lineLimit ) throws IOException {
125
+ /**
126
+ * Setting fileTypeName has to happen before getFieldHighlighter() is
127
+ * called by highlightFieldsAsObjects() so that the result of
128
+ * getIndexAnalyzer() (if it is called due to requiring ANALYSIS) can be
129
+ * influenced by fileTypeName.
130
+ */
131
+ Document doc = searcher .doc (docId );
132
+ fileTypeName = doc == null ? null : doc .get (QueryBuilder .TYPE );
133
+ try {
134
+ return highlightFieldsUnionWork (fields , query , docId , lineLimit );
135
+ } finally {
136
+ fileTypeName = null ;
137
+ }
138
+ }
139
+
93
140
/**
94
141
* Calls
95
142
* {@link #highlightFieldsAsObjects(java.lang.String[], org.apache.lucene.search.Query, int[], int[])},
@@ -99,10 +146,10 @@ public void setTabSize(int value) {
99
146
* @param query a defined instance
100
147
* @param docId a valid document ID
101
148
* @param lineLimit the maximum number of lines to return
102
- * @return {@code null} if there are no results or a defined instance
103
- * @throws IOException
149
+ * @return a defined instance or else {@code null} if there are no results
150
+ * @throws IOException if accessing the Lucene document fails
104
151
*/
105
- public String highlightFieldsUnion (String [] fields , Query query ,
152
+ protected String highlightFieldsUnionWork (String [] fields , Query query ,
106
153
int docId , int lineLimit ) throws IOException {
107
154
int [] maxPassagesCopy = new int [fields .length ];
108
155
/**
@@ -154,9 +201,6 @@ public String highlightFieldsUnion(String[] fields, Query query,
154
201
* {@code cacheCharsThreshold} is exceeded. Specifically if that number is
155
202
* 0, then only one document is fetched no matter what. Values in the array
156
203
* of {@link CharSequence} will be {@code null} if no value was found."
157
- * @param fields
158
- * @param docIter
159
- * @param cacheCharsThreshold
160
204
* @return a defined instance
161
205
* @throws IOException if an I/O error occurs
162
206
*/
@@ -214,13 +258,11 @@ protected OffsetSource getOptimizedOffsetSource(String field,
214
258
* postings should be sufficient in the comment for
215
259
* shouldHandleMultiTermQuery(String): "MTQ highlighting can be
216
260
* expensive, particularly when using offsets in postings."
217
- * DEFS are stored with term vectors to avoid this problem.
218
- * FULL should be approximately fine with re-analysis using an
219
- * on-the-fly PlainAnalyzer.
220
- * REFS should be approximately fine with re-analysis using an
221
- * on-the-fly PlainAnalyzer. It might not accord with the true
222
- * language symbol tokenizer, but it should not be wildly
223
- * divergent.
261
+ * DEFS are stored with term vectors to avoid this problem,
262
+ * since re-analysis would not at all accord with ctags Definitions.
263
+ * For FULL and REFS, highlightFieldsUnion() arranges that
264
+ * getIndexAnalyzer() can return a TYPE-specific analyzer for use by
265
+ * getOffsetStrategy() -- if re-ANALYSIS is required.
224
266
*/
225
267
switch (field ) {
226
268
case QueryBuilder .FULL :
0 commit comments