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