blob: d0dd93f20a6e7bdfc0d54a9fc0a2f8321fb31ed3 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.docmlet.base.core;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.text.core.SearchPattern;
@NonNullByDefault
public class DocmlSearchPattern extends SearchPattern {
public static final int LABEL_SUBSTRING_MATCH= 1 << 21;
private static final int NOT_CHECKED= -1;
private static final int NOT_AVAILABLE= -2;
private int labelPrefixIdx= NOT_CHECKED;
public DocmlSearchPattern(final int rules, final String pattern) {
super(rules, pattern);
}
@Override
public int getSupportedRules() {
return (PREFIX_MATCH | SUBSTRING_MATCH | LABEL_SUBSTRING_MATCH);
}
@Override
protected void onPatternChanged(final String pattern) {
this.labelPrefixIdx= NOT_CHECKED;
}
private int getLabelPrefixIdx() {
int labelPrefixIdx= this.labelPrefixIdx;
if (labelPrefixIdx == NOT_CHECKED) {
labelPrefixIdx= NOT_AVAILABLE;
final char[] patternChars= getPatternChars();
for (int idx= 0; idx < patternChars.length; idx++) {
if (patternChars[idx] == ':') {
labelPrefixIdx= idx;
break;
}
}
this.labelPrefixIdx= labelPrefixIdx;
}
return labelPrefixIdx;
}
@Override
public int matches(final String name) {
final int allowedRules= getRules();
char[] patternChars= null;
char[] nameChars= null;
final int patternLength= getPattern().length();
final int lDiff= name.length() - patternLength;
if (lDiff >= 0) {
if ((allowedRules & PREFIX_MATCH) != 0
&& (patternLength == 0
|| isPrefixMatch(patternChars= getPatternChars(), 0, patternChars.length,
name, 0, name.length() ) )) {
return PREFIX_MATCH;
}
if (lDiff > 0) {
if ((allowedRules & LABEL_SUBSTRING_MATCH) != 0) {
final int labelPrefixIdx= getLabelPrefixIdx() + 1;
if (labelPrefixIdx > 0) {
if (isPrefixMatch(patternChars= getPatternChars(), 0, labelPrefixIdx,
nameChars= getNameChars(name), 0, name.length() )
&& isSubstringMatch(patternChars, labelPrefixIdx, patternChars.length,
nameChars, labelPrefixIdx + 1, nameChars.length )) {
return LABEL_SUBSTRING_MATCH;
}
}
}
if ((allowedRules & SUBSTRING_MATCH) != 0
&& isSubstringMatch(patternChars= getPatternChars(), 0, patternChars.length,
nameChars= getNameChars(name), 1, nameChars.length )) {
return SUBSTRING_MATCH;
}
}
}
return 0;
}
@Override
public int @Nullable [] getMatchingRegions(final String name, final int matchRule) {
switch (matchRule) {
case LABEL_SUBSTRING_MATCH:
return getLabelSubstringMatchingRegions(name);
default:
return super.getMatchingRegions(name, matchRule);
}
}
private int[] getLabelSubstringMatchingRegions(final String name) {
final char[] patternChars;
final char[] nameChars;
final int labelPrefixIdx= getLabelPrefixIdx() + 1;
this.tmpRegions.clear();
addPrefixMatch(0, labelPrefixIdx, 0);
addSubstringMatches(patternChars= getPatternChars(), labelPrefixIdx, patternChars.length,
nameChars= getNameChars(name), labelPrefixIdx + 1, nameChars.length );
return this.tmpRegions.toArray();
}
}