xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/JFlexSymbolMatcher.java (revision 5d9f3aa0ca3da3a714233f987fa732f62c0965f6)
1b5840353SAdam Hornáček /*
2b5840353SAdam Hornáček  * CDDL HEADER START
3b5840353SAdam Hornáček  *
4b5840353SAdam Hornáček  * The contents of this file are subject to the terms of the
5b5840353SAdam Hornáček  * Common Development and Distribution License (the "License").
6b5840353SAdam Hornáček  * You may not use this file except in compliance with the License.
7b5840353SAdam Hornáček  *
8b5840353SAdam Hornáček  * See LICENSE.txt included in this distribution for the specific
9b5840353SAdam Hornáček  * language governing permissions and limitations under the License.
10b5840353SAdam Hornáček  *
11b5840353SAdam Hornáček  * When distributing Covered Code, include this CDDL HEADER in each
12b5840353SAdam Hornáček  * file and include the License file at LICENSE.txt.
13b5840353SAdam Hornáček  * If applicable, add the following below this CDDL HEADER, with the
14b5840353SAdam Hornáček  * fields enclosed by brackets "[]" replaced with your own identifying
15b5840353SAdam Hornáček  * information: Portions Copyright [yyyy] [name of copyright owner]
16b5840353SAdam Hornáček  *
17b5840353SAdam Hornáček  * CDDL HEADER END
18b5840353SAdam Hornáček  */
19b5840353SAdam Hornáček 
20b5840353SAdam Hornáček /*
21*5d9f3aa0SAdam Hornáček  * Copyright (c) 2017, 2020, Chris Fraire <cfraire@me.com>.
22b5840353SAdam Hornáček  */
239805b761SAdam Hornáček package org.opengrok.indexer.analysis;
24b5840353SAdam Hornáček 
2552dccac1SChris Fraire import java.util.Locale;
26b5840353SAdam Hornáček import java.util.Set;
270e717e6aSChris Fraire import java.util.regex.Matcher;
28b5840353SAdam Hornáček import java.util.regex.Pattern;
299805b761SAdam Hornáček import org.opengrok.indexer.util.StringUtils;
30fb1fd46dSChris Fraire import org.opengrok.indexer.util.UriUtils;
31b5840353SAdam Hornáček 
32b5840353SAdam Hornáček /**
33b5840353SAdam Hornáček  * Represents an abstract base class for subclasses of
34b5840353SAdam Hornáček  * {@link JFlexStateStacker} that can publish as {@link ScanningSymbolMatcher}.
35b5840353SAdam Hornáček  */
36b5840353SAdam Hornáček public abstract class JFlexSymbolMatcher extends JFlexStateStacker
37b5840353SAdam Hornáček         implements ScanningSymbolMatcher {
38b5840353SAdam Hornáček 
39b5840353SAdam Hornáček     private SymbolMatchedListener symbolListener;
40b5840353SAdam Hornáček     private NonSymbolMatchedListener nonSymbolListener;
41b5840353SAdam Hornáček     private String disjointSpanClassName;
42b5840353SAdam Hornáček 
43b5840353SAdam Hornáček     /**
44b5840353SAdam Hornáček      * Associates the specified listener, replacing the former one.
45b5840353SAdam Hornáček      * @param l defined instance
46b5840353SAdam Hornáček      */
47b5840353SAdam Hornáček     @Override
setSymbolMatchedListener(SymbolMatchedListener l)48b5840353SAdam Hornáček     public void setSymbolMatchedListener(SymbolMatchedListener l) {
49b5840353SAdam Hornáček         if (l == null) {
50b5840353SAdam Hornáček             throw new IllegalArgumentException("`l' is null");
51b5840353SAdam Hornáček         }
52b5840353SAdam Hornáček         symbolListener = l;
53b5840353SAdam Hornáček     }
54b5840353SAdam Hornáček 
55b5840353SAdam Hornáček     /**
56b5840353SAdam Hornáček      * Clears any association to a listener.
57b5840353SAdam Hornáček      */
58b5840353SAdam Hornáček     @Override
clearSymbolMatchedListener()59b5840353SAdam Hornáček     public void clearSymbolMatchedListener() {
60b5840353SAdam Hornáček         symbolListener = null;
61b5840353SAdam Hornáček     }
62b5840353SAdam Hornáček 
63b5840353SAdam Hornáček     /**
64b5840353SAdam Hornáček      * Associates the specified listener, replacing the former one.
65b5840353SAdam Hornáček      * @param l defined instance
66b5840353SAdam Hornáček      */
67b5840353SAdam Hornáček     @Override
setNonSymbolMatchedListener(NonSymbolMatchedListener l)68b5840353SAdam Hornáček     public void setNonSymbolMatchedListener(NonSymbolMatchedListener l) {
69b5840353SAdam Hornáček         if (l == null) {
70b5840353SAdam Hornáček             throw new IllegalArgumentException("`l' is null");
71b5840353SAdam Hornáček         }
72b5840353SAdam Hornáček         nonSymbolListener = l;
73b5840353SAdam Hornáček     }
74b5840353SAdam Hornáček 
75b5840353SAdam Hornáček     /**
76b5840353SAdam Hornáček      * Clears any association to a listener.
77b5840353SAdam Hornáček      */
78b5840353SAdam Hornáček     @Override
clearNonSymbolMatchedListener()79b5840353SAdam Hornáček     public void clearNonSymbolMatchedListener() {
80b5840353SAdam Hornáček         nonSymbolListener = null;
81b5840353SAdam Hornáček     }
82b5840353SAdam Hornáček 
83b5840353SAdam Hornáček     /**
84b5840353SAdam Hornáček      * Gets the class name value from the last call to
85d051e170SChris Fraire      * {@link #onDisjointSpanChanged(String, long)}.
86b5840353SAdam Hornáček      * @return a defined value or null
87b5840353SAdam Hornáček      */
getDisjointSpanClassName()88b5840353SAdam Hornáček     protected String getDisjointSpanClassName() {
89b5840353SAdam Hornáček         return disjointSpanClassName;
90b5840353SAdam Hornáček     }
91b5840353SAdam Hornáček 
92b5840353SAdam Hornáček     /**
93b5840353SAdam Hornáček      * Raises
949805b761SAdam Hornáček      * {@link SymbolMatchedListener#symbolMatched(org.opengrok.indexer.analysis.SymbolMatchedEvent)}
95b5840353SAdam Hornáček      * for a subscribed listener.
96b5840353SAdam Hornáček      * @param str the symbol string
97b5840353SAdam Hornáček      * @param start the symbol start position
98b5840353SAdam Hornáček      */
onSymbolMatched(String str, long start)99d051e170SChris Fraire     protected void onSymbolMatched(String str, long start) {
100b5840353SAdam Hornáček         SymbolMatchedListener l = symbolListener;
101b5840353SAdam Hornáček         if (l != null) {
102b5840353SAdam Hornáček             SymbolMatchedEvent evt = new SymbolMatchedEvent(this, str, start,
103b5840353SAdam Hornáček                 start + str.length());
104b5840353SAdam Hornáček             l.symbolMatched(evt);
105b5840353SAdam Hornáček         }
106b5840353SAdam Hornáček     }
107b5840353SAdam Hornáček 
108b5840353SAdam Hornáček     /**
109b5840353SAdam Hornáček      * Raises
1109805b761SAdam Hornáček      * {@link SymbolMatchedListener#sourceCodeSeen(org.opengrok.indexer.analysis.SourceCodeSeenEvent)}
111b5840353SAdam Hornáček      * for all subscribed listeners in turn.
112b5840353SAdam Hornáček      * @param start the source code start position
113b5840353SAdam Hornáček      */
onSourceCodeSeen(long start)114d051e170SChris Fraire     protected void onSourceCodeSeen(long start) {
115b5840353SAdam Hornáček         SymbolMatchedListener l = symbolListener;
116b5840353SAdam Hornáček         if (l != null) {
117b5840353SAdam Hornáček             SourceCodeSeenEvent evt = new SourceCodeSeenEvent(this, start);
118b5840353SAdam Hornáček             l.sourceCodeSeen(evt);
119b5840353SAdam Hornáček         }
120b5840353SAdam Hornáček     }
121b5840353SAdam Hornáček 
122b5840353SAdam Hornáček     /**
123d051e170SChris Fraire      * Calls {@link #onNonSymbolMatched(String, long)} with the
124b5840353SAdam Hornáček      * {@link String#valueOf(char)} {@code c} and {@code start}.
125b5840353SAdam Hornáček      * @param c the text character
126b5840353SAdam Hornáček      * @param start the text start position
127b5840353SAdam Hornáček      */
onNonSymbolMatched(char c, long start)128d051e170SChris Fraire     protected void onNonSymbolMatched(char c, long start) {
129b5840353SAdam Hornáček         onNonSymbolMatched(String.valueOf(c), start);
130b5840353SAdam Hornáček     }
131b5840353SAdam Hornáček 
132b5840353SAdam Hornáček     /**
133b5840353SAdam Hornáček      * Raises
1349805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#nonSymbolMatched(org.opengrok.indexer.analysis.TextMatchedEvent)}
135b5840353SAdam Hornáček      * for a subscribed listener.
136b5840353SAdam Hornáček      * @param str the text string
137b5840353SAdam Hornáček      * @param start the text start position
138b5840353SAdam Hornáček      */
onNonSymbolMatched(String str, long start)139d051e170SChris Fraire     protected void onNonSymbolMatched(String str, long start) {
140b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
141b5840353SAdam Hornáček         if (l != null) {
142b5840353SAdam Hornáček             TextMatchedEvent evt = new TextMatchedEvent(this, str, start,
143b5840353SAdam Hornáček                 start + str.length());
144b5840353SAdam Hornáček             l.nonSymbolMatched(evt);
145b5840353SAdam Hornáček         }
146b5840353SAdam Hornáček     }
147b5840353SAdam Hornáček 
148b5840353SAdam Hornáček     /**
149b5840353SAdam Hornáček      * Raises
1509805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#nonSymbolMatched(org.opengrok.indexer.analysis.TextMatchedEvent)}
151b5840353SAdam Hornáček      * for a subscribed listener.
152b5840353SAdam Hornáček      * @param str the text string
153b5840353SAdam Hornáček      * @param hint the text hint
154b5840353SAdam Hornáček      * @param start the text start position
155b5840353SAdam Hornáček      */
onNonSymbolMatched(String str, EmphasisHint hint, long start)156d051e170SChris Fraire     protected void onNonSymbolMatched(String str, EmphasisHint hint, long start) {
157b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
158b5840353SAdam Hornáček         if (l != null) {
159b5840353SAdam Hornáček             TextMatchedEvent evt = new TextMatchedEvent(this, str, hint, start,
160b5840353SAdam Hornáček                 start + str.length());
161b5840353SAdam Hornáček             l.nonSymbolMatched(evt);
162b5840353SAdam Hornáček         }
163b5840353SAdam Hornáček     }
164b5840353SAdam Hornáček 
165b5840353SAdam Hornáček     /**
166b5840353SAdam Hornáček      * Raises
1679805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#keywordMatched(org.opengrok.indexer.analysis.TextMatchedEvent)}
168b5840353SAdam Hornáček      * for a subscribed listener.
169b5840353SAdam Hornáček      * @param str the text string
170b5840353SAdam Hornáček      * @param start the text start position
171b5840353SAdam Hornáček      */
onKeywordMatched(String str, long start)172d051e170SChris Fraire     protected void onKeywordMatched(String str, long start) {
173b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
174b5840353SAdam Hornáček         if (l != null) {
175b5840353SAdam Hornáček             TextMatchedEvent evt = new TextMatchedEvent(this, str, start,
176b5840353SAdam Hornáček                 start + str.length());
177b5840353SAdam Hornáček             l.keywordMatched(evt);
178b5840353SAdam Hornáček         }
179b5840353SAdam Hornáček     }
180b5840353SAdam Hornáček 
181b5840353SAdam Hornáček     /**
182b5840353SAdam Hornáček      * Calls {@link #setLineNumber(int)} with the sum of
183b5840353SAdam Hornáček      * {@link #getLineNumber()} and the number of LFs in {@code str}, and then
184b5840353SAdam Hornáček      * raises
1859805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#endOfLineMatched(org.opengrok.indexer.analysis.TextMatchedEvent)}
186b5840353SAdam Hornáček      * for a subscribed listener.
187b5840353SAdam Hornáček      * @param str the text string
188b5840353SAdam Hornáček      * @param start the text start position
189b5840353SAdam Hornáček      */
onEndOfLineMatched(String str, long start)190d051e170SChris Fraire     protected void onEndOfLineMatched(String str, long start) {
1910e717e6aSChris Fraire         setLineNumber(getLineNumber() + countEOLs(str));
192b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
193b5840353SAdam Hornáček         if (l != null) {
194b5840353SAdam Hornáček             TextMatchedEvent evt = new TextMatchedEvent(this, str, start,
195b5840353SAdam Hornáček                 start + str.length());
196b5840353SAdam Hornáček             l.endOfLineMatched(evt);
197b5840353SAdam Hornáček         }
198b5840353SAdam Hornáček     }
199b5840353SAdam Hornáček 
200b5840353SAdam Hornáček     /**
201b5840353SAdam Hornáček      * Raises
2029805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#disjointSpanChanged(org.opengrok.indexer.analysis.DisjointSpanChangedEvent)}
203b5840353SAdam Hornáček      * for a subscribed listener.
204b5840353SAdam Hornáček      * @param className the text string
205b5840353SAdam Hornáček      * @param position the text position
206b5840353SAdam Hornáček      */
onDisjointSpanChanged(String className, long position)207d051e170SChris Fraire     protected void onDisjointSpanChanged(String className, long position) {
208b5840353SAdam Hornáček         disjointSpanClassName = className;
209b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
210b5840353SAdam Hornáček         if (l != null) {
211b5840353SAdam Hornáček             DisjointSpanChangedEvent evt = new DisjointSpanChangedEvent(this,
212b5840353SAdam Hornáček                 className, position);
213b5840353SAdam Hornáček             l.disjointSpanChanged(evt);
214b5840353SAdam Hornáček         }
215b5840353SAdam Hornáček     }
216b5840353SAdam Hornáček 
217b5840353SAdam Hornáček     /**
218b5840353SAdam Hornáček      * Calls
219d051e170SChris Fraire      * {@link #onUriMatched(String, long, Pattern)}
220b5840353SAdam Hornáček      * with {@code uri}, {@code start}, and {@code null}.
221b5840353SAdam Hornáček      * @param uri the URI string
222b5840353SAdam Hornáček      * @param start the URI start position
223b5840353SAdam Hornáček      */
onUriMatched(String uri, long start)224d051e170SChris Fraire     protected void onUriMatched(String uri, long start) {
225b5840353SAdam Hornáček         onUriMatched(uri, start, null);
226b5840353SAdam Hornáček     }
227b5840353SAdam Hornáček 
228b5840353SAdam Hornáček     /**
229b5840353SAdam Hornáček      * Raises
2309805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
231b5840353SAdam Hornáček      * of {@link LinkageType#URI} for a subscribed listener.
232b5840353SAdam Hornáček      * <p>First, the end of {@code uri} is possibly trimmed (with a
233b5840353SAdam Hornáček      * corresponding call to {@link #yypushback(int)}) based on the result
234b5840353SAdam Hornáček      * of {@link StringUtils#countURIEndingPushback(java.lang.String)} and
235b5840353SAdam Hornáček      * optionally
236b5840353SAdam Hornáček      * {@link StringUtils#countPushback(java.lang.String, java.util.regex.Pattern)}
237b5840353SAdam Hornáček      * if {@code collateralCapture} is not null.
238b5840353SAdam Hornáček      * <p>If the pushback count is equal to the length of {@code url}, then it
239b5840353SAdam Hornáček      * is simply written -- and nothing is pushed back -- in order to avoid a
240b5840353SAdam Hornáček      * never-ending {@code yylex()} loop.
241b5840353SAdam Hornáček      *
242b5840353SAdam Hornáček      * @param uri the URI string
243b5840353SAdam Hornáček      * @param start the URI start position
244b5840353SAdam Hornáček      * @param collateralCapture optional pattern to indicate characters which
245b5840353SAdam Hornáček      * may have been captured as valid URI characters but in a particular
246b5840353SAdam Hornáček      * context should mark the start of a pushback
247b5840353SAdam Hornáček      */
onUriMatched(String uri, long start, Pattern collateralCapture)248d051e170SChris Fraire     protected void onUriMatched(String uri, long start, Pattern collateralCapture) {
249fb1fd46dSChris Fraire         UriUtils.TrimUriResult result = UriUtils.trimUri(uri, true, collateralCapture);
250fb1fd46dSChris Fraire         if (result.getPushBackCount() > 0) {
251fb1fd46dSChris Fraire             yypushback(result.getPushBackCount());
252a72324b1SAdam Hornáček         }
253b5840353SAdam Hornáček 
254b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
255b5840353SAdam Hornáček         if (l != null) {
256fb1fd46dSChris Fraire             uri = result.getUri();
257b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, uri,
258b5840353SAdam Hornáček                 LinkageType.URI, start, start + uri.length());
259b5840353SAdam Hornáček             l.linkageMatched(evt);
260b5840353SAdam Hornáček         }
261b5840353SAdam Hornáček     }
262b5840353SAdam Hornáček 
263b5840353SAdam Hornáček     /**
264b5840353SAdam Hornáček      * Raises
2659805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
266b5840353SAdam Hornáček      * of {@link LinkageType#FILELIKE} for a subscribed listener.
267b5840353SAdam Hornáček      * @param str the text string
268b5840353SAdam Hornáček      * @param start the text start position
269b5840353SAdam Hornáček      */
onFilelikeMatched(String str, long start)270d051e170SChris Fraire     protected void onFilelikeMatched(String str, long start) {
271b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
272b5840353SAdam Hornáček         if (l != null) {
273b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
274b5840353SAdam Hornáček                 LinkageType.FILELIKE, start, start + str.length());
275b5840353SAdam Hornáček             l.linkageMatched(evt);
276b5840353SAdam Hornáček         }
277b5840353SAdam Hornáček     }
278b5840353SAdam Hornáček 
279b5840353SAdam Hornáček     /**
280b5840353SAdam Hornáček      * Raises
2819805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#pathlikeMatched(org.opengrok.indexer.analysis.PathlikeMatchedEvent)}
282b5840353SAdam Hornáček      * for a subscribed listener.
283b5840353SAdam Hornáček      * @param str the path text string
284b5840353SAdam Hornáček      * @param sep the path separator
285b5840353SAdam Hornáček      * @param canonicalize a value indicating whether the path should be
286b5840353SAdam Hornáček      * canonicalized
287b5840353SAdam Hornáček      * @param start the text start position
288b5840353SAdam Hornáček      */
onPathlikeMatched(String str, char sep, boolean canonicalize, long start)289d051e170SChris Fraire     protected void onPathlikeMatched(String str, char sep, boolean canonicalize, long start) {
290b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
291b5840353SAdam Hornáček         if (l != null) {
292b5840353SAdam Hornáček             PathlikeMatchedEvent  evt = new PathlikeMatchedEvent(this, str,
293b5840353SAdam Hornáček                 sep, canonicalize, start, start + str.length());
294b5840353SAdam Hornáček             l.pathlikeMatched(evt);
295b5840353SAdam Hornáček         }
296b5840353SAdam Hornáček     }
297b5840353SAdam Hornáček 
298b5840353SAdam Hornáček     /**
299b5840353SAdam Hornáček      * Raises
3009805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
301b5840353SAdam Hornáček      * of {@link LinkageType#EMAIL} for a subscribed listener.
302b5840353SAdam Hornáček      * @param str the text string
303b5840353SAdam Hornáček      * @param start the text start position
304b5840353SAdam Hornáček      */
onEmailAddressMatched(String str, long start)305d051e170SChris Fraire     protected void onEmailAddressMatched(String str, long start) {
306b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
307b5840353SAdam Hornáček         if (l != null) {
308b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
309b5840353SAdam Hornáček                 LinkageType.EMAIL, start, start + str.length());
310b5840353SAdam Hornáček             l.linkageMatched(evt);
311b5840353SAdam Hornáček         }
312b5840353SAdam Hornáček     }
313b5840353SAdam Hornáček 
314b5840353SAdam Hornáček     /**
315b5840353SAdam Hornáček      * Raises
3169805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
317b5840353SAdam Hornáček      * of {@link LinkageType#LABEL} for a subscribed listener.
318b5840353SAdam Hornáček      * @param str the text string (literal capture)
319b5840353SAdam Hornáček      * @param start the text start position
320b5840353SAdam Hornáček      * @param lstr the text link string
321b5840353SAdam Hornáček      */
onLabelMatched(String str, long start, String lstr)322d051e170SChris Fraire     protected void onLabelMatched(String str, long start, String lstr) {
323b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
324b5840353SAdam Hornáček         if (l != null) {
325b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
326b5840353SAdam Hornáček                 LinkageType.LABEL, start, start + str.length(), lstr);
327b5840353SAdam Hornáček             l.linkageMatched(evt);
328b5840353SAdam Hornáček         }
329b5840353SAdam Hornáček     }
330b5840353SAdam Hornáček 
331b5840353SAdam Hornáček     /**
332b5840353SAdam Hornáček      * Raises
3339805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
334b5840353SAdam Hornáček      * of {@link LinkageType#LABELDEF} for a subscribed listener.
335b5840353SAdam Hornáček      * @param str the text string (literal capture)
336b5840353SAdam Hornáček      * @param start the text start position
337b5840353SAdam Hornáček      */
onLabelDefMatched(String str, long start)338d051e170SChris Fraire     protected void onLabelDefMatched(String str, long start) {
339b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
340b5840353SAdam Hornáček         if (l != null) {
341b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
342b5840353SAdam Hornáček                 LinkageType.LABELDEF, start, start + str.length());
343b5840353SAdam Hornáček             l.linkageMatched(evt);
344b5840353SAdam Hornáček         }
345b5840353SAdam Hornáček     }
346b5840353SAdam Hornáček 
347b5840353SAdam Hornáček     /**
348b5840353SAdam Hornáček      * Raises
3499805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
350b5840353SAdam Hornáček      * of {@link LinkageType#QUERY} for a subscribed listener.
351b5840353SAdam Hornáček      * @param str the text string
352b5840353SAdam Hornáček      * @param start the text start position
353b5840353SAdam Hornáček      */
onQueryTermMatched(String str, long start)354d051e170SChris Fraire     protected void onQueryTermMatched(String str, long start) {
355b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
356b5840353SAdam Hornáček         if (l != null) {
357b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
358b5840353SAdam Hornáček                 LinkageType.QUERY, start, start + str.length());
359b5840353SAdam Hornáček             l.linkageMatched(evt);
360b5840353SAdam Hornáček         }
361b5840353SAdam Hornáček     }
362b5840353SAdam Hornáček 
363b5840353SAdam Hornáček     /**
364b5840353SAdam Hornáček      * Raises
3659805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#linkageMatched(org.opengrok.indexer.analysis.LinkageMatchedEvent)}
366b5840353SAdam Hornáček      * of {@link LinkageType#REFS} for a subscribed listener.
367b5840353SAdam Hornáček      * @param str the text string
368b5840353SAdam Hornáček      * @param start the text start position
369b5840353SAdam Hornáček      */
onRefsTermMatched(String str, long start)370d051e170SChris Fraire     protected void onRefsTermMatched(String str, long start) {
371b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
372b5840353SAdam Hornáček         if (l != null) {
373b5840353SAdam Hornáček             LinkageMatchedEvent evt = new LinkageMatchedEvent(this, str,
374b5840353SAdam Hornáček                 LinkageType.REFS, start, start + str.length());
375b5840353SAdam Hornáček             l.linkageMatched(evt);
376b5840353SAdam Hornáček         }
377b5840353SAdam Hornáček     }
378b5840353SAdam Hornáček 
379b5840353SAdam Hornáček     /**
380b5840353SAdam Hornáček      * Raises
3819805b761SAdam Hornáček      * {@link NonSymbolMatchedListener#scopeChanged(org.opengrok.indexer.analysis.ScopeChangedEvent)}
382b5840353SAdam Hornáček      * for a subscribed listener.
383b5840353SAdam Hornáček      * @param action the scope change action
384b5840353SAdam Hornáček      * @param str the text string
385b5840353SAdam Hornáček      * @param start the text start position
386b5840353SAdam Hornáček      */
onScopeChanged(ScopeAction action, String str, long start)387d051e170SChris Fraire     protected void onScopeChanged(ScopeAction action, String str, long start) {
388b5840353SAdam Hornáček         NonSymbolMatchedListener l = nonSymbolListener;
389b5840353SAdam Hornáček         if (l != null) {
390b5840353SAdam Hornáček             ScopeChangedEvent evt = new ScopeChangedEvent(this, action, str,
391b5840353SAdam Hornáček                 start, start + str.length());
392b5840353SAdam Hornáček             l.scopeChanged(evt);
393b5840353SAdam Hornáček         }
394b5840353SAdam Hornáček     }
395b5840353SAdam Hornáček 
396b5840353SAdam Hornáček     /**
397b5840353SAdam Hornáček      * Calls
398d051e170SChris Fraire      * {@link #onFilteredSymbolMatched(String, long, Set, boolean)}
399b5840353SAdam Hornáček      * with {@code str}, {@code start}, {@code keywords}, and {@code true}.
400b5840353SAdam Hornáček      * @param str the text string
401b5840353SAdam Hornáček      * @param start the text start position
402b5840353SAdam Hornáček      * @param keywords an optional set to search for {@code str} as a member to
403b5840353SAdam Hornáček      * indicate a keyword
404b5840353SAdam Hornáček      * @return true if the {@code str} was not in {@code keywords} or if
405b5840353SAdam Hornáček      * {@code keywords} was null
406b5840353SAdam Hornáček      */
onFilteredSymbolMatched(String str, long start, Set<String> keywords)407d051e170SChris Fraire     protected boolean onFilteredSymbolMatched(String str, long start, Set<String> keywords) {
408b5840353SAdam Hornáček         return onFilteredSymbolMatched(str, start, keywords, true);
409b5840353SAdam Hornáček     }
410b5840353SAdam Hornáček 
411b5840353SAdam Hornáček     /**
412d051e170SChris Fraire      * Raises {@link #onKeywordMatched(String, long)} if
413b5840353SAdam Hornáček      * {@code keywords} is not null and {@code str} is found as a member (in a
414b5840353SAdam Hornáček      * case-sensitive or case-less search per {@code caseSensitive}); otherwise
415d051e170SChris Fraire      * raises {@link #onSymbolMatched(String, long)}.
416b5840353SAdam Hornáček      * @param str the text string
417b5840353SAdam Hornáček      * @param start the text start position
418b5840353SAdam Hornáček      * @param keywords an optional set to search for {@code str} as a member to
419b5840353SAdam Hornáček      * indicate a keyword
420b5840353SAdam Hornáček      * @param caseSensitive a value indicating if {@code keywords} should be
421b5840353SAdam Hornáček      * searched for {@code str} as-is ({@code true}) or if the lower-case
422b5840353SAdam Hornáček      * equivalent of {@code str} should be used ({@code false}).
423b5840353SAdam Hornáček      * @return true if the {@code str} was not in {@code keywords} or if
424b5840353SAdam Hornáček      * {@code keywords} was null
425b5840353SAdam Hornáček      */
onFilteredSymbolMatched(String str, long start, Set<String> keywords, boolean caseSensitive)426d051e170SChris Fraire     protected boolean onFilteredSymbolMatched(String str, long start, Set<String> keywords,
427d051e170SChris Fraire             boolean caseSensitive) {
428b5840353SAdam Hornáček 
429b5840353SAdam Hornáček         if (keywords != null) {
43052dccac1SChris Fraire             String check = caseSensitive ? str : str.toLowerCase(Locale.ROOT);
431b5840353SAdam Hornáček             if (keywords.contains(check)) {
432b5840353SAdam Hornáček                 onKeywordMatched(str, start);
433b5840353SAdam Hornáček                 return false;
434b5840353SAdam Hornáček             }
435b5840353SAdam Hornáček         }
436b5840353SAdam Hornáček         onSymbolMatched(str, start);
437b5840353SAdam Hornáček         return true;
438b5840353SAdam Hornáček     }
439b5840353SAdam Hornáček 
countEOLs(String str)4400e717e6aSChris Fraire     private static int countEOLs(String str) {
4410e717e6aSChris Fraire         Matcher m = StringUtils.STANDARD_EOL.matcher(str);
442b5840353SAdam Hornáček         int n = 0;
4430e717e6aSChris Fraire         while (m.find()) {
444a72324b1SAdam Hornáček             ++n;
445a72324b1SAdam Hornáček         }
446b5840353SAdam Hornáček         return n;
447b5840353SAdam Hornáček     }
448b5840353SAdam Hornáček }
449