4141import org .apache .lucene .search .uhighlight .UnifiedHighlighter ;
4242import org .apache .lucene .util .BytesRef ;
4343import org .apache .lucene .util .automaton .CharacterRunAutomaton ;
44+ import org .opensolaris .opengrok .analysis .AnalyzerGuru ;
4445import org .opensolaris .opengrok .analysis .ExpandTabsReader ;
4546import org .opensolaris .opengrok .analysis .StreamSource ;
4647import org .opensolaris .opengrok .configuration .RuntimeEnvironment ;
@@ -62,6 +63,8 @@ public class OGKUnifiedHighlighter extends UnifiedHighlighter {
6263
6364 private int tabSize ;
6465
66+ private String fileTypeName ;
67+
6568 /**
6669 * Initializes an instance with
6770 * {@link UnifiedHighlighter#UnifiedHighlighter(org.apache.lucene.search.IndexSearcher, org.apache.lucene.analysis.Analyzer)}
@@ -82,6 +85,22 @@ public OGKUnifiedHighlighter(RuntimeEnvironment env,
8285 this .env = env ;
8386 }
8487
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+
85104 public int getTabSize () {
86105 return tabSize ;
87106 }
@@ -90,6 +109,34 @@ public void setTabSize(int value) {
90109 this .tabSize = value ;
91110 }
92111
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+
93140 /**
94141 * Calls
95142 * {@link #highlightFieldsAsObjects(java.lang.String[], org.apache.lucene.search.Query, int[], int[])},
@@ -99,10 +146,10 @@ public void setTabSize(int value) {
99146 * @param query a defined instance
100147 * @param docId a valid document ID
101148 * @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
104151 */
105- public String highlightFieldsUnion (String [] fields , Query query ,
152+ protected String highlightFieldsUnionWork (String [] fields , Query query ,
106153 int docId , int lineLimit ) throws IOException {
107154 int [] maxPassagesCopy = new int [fields .length ];
108155 /**
@@ -154,9 +201,6 @@ public String highlightFieldsUnion(String[] fields, Query query,
154201 * {@code cacheCharsThreshold} is exceeded. Specifically if that number is
155202 * 0, then only one document is fetched no matter what. Values in the array
156203 * of {@link CharSequence} will be {@code null} if no value was found."
157- * @param fields
158- * @param docIter
159- * @param cacheCharsThreshold
160204 * @return a defined instance
161205 * @throws IOException if an I/O error occurs
162206 */
@@ -214,13 +258,11 @@ protected OffsetSource getOptimizedOffsetSource(String field,
214258 * postings should be sufficient in the comment for
215259 * shouldHandleMultiTermQuery(String): "MTQ highlighting can be
216260 * 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.
224266 */
225267 switch (field ) {
226268 case QueryBuilder .FULL :
0 commit comments