com.aspectran.core.util.wildcard.WildcardMasker Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2023 The Aspectran Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.aspectran.core.util.wildcard;
/**
* Erase the characters that does not corresponds to the wildcard, and
* returns collect only the remaining characters. In other words,
* only the characters that correspond to wildcards are left.
*/
public class WildcardMasker {
/**
* Erase the characters that does not corresponds to the wildcard, and
* returns collect only the remaining characters. In other words,
* only the characters that correspond to wildcards are left.
* @param pattern the pattern to match
* @param input the input string
* @return the remains string
*/
public static String mask(WildcardPattern pattern, CharSequence input) {
char[] tokens = pattern.getTokens();
int[] types = pattern.getTypes();
char separator = pattern.getSeparator();
int tlen = tokens.length;
int clen = input.length();
char[] masks = new char[clen];
char c;
int tidx = 0;
int cidx = 0;
int trng1;
int trng2;
int ttemp;
int crng1;
int crng2;
int ctmp;
int scnt1;
int scnt2;
while (tidx < tlen && cidx < clen) {
if (types[tidx] == WildcardPattern.LITERAL_TYPE) {
if (tokens[tidx++] != input.charAt(cidx++)) {
return null;
}
} else if (types[tidx] == WildcardPattern.STAR_TYPE) {
trng1 = tidx + 1;
if (trng1 < tlen) {
trng2 = trng1;
for (; trng2 < tlen; trng2++) {
if (types[trng2] == WildcardPattern.EOT_TYPE
|| types[trng2] != WildcardPattern.LITERAL_TYPE) {
break;
}
}
if (trng1 == trng2) {
// prefix*
for (; cidx < clen; cidx++) {
c = input.charAt(cidx);
if (c == separator) {
break;
}
masks[cidx] = c;
}
tidx++;
} else {
// *suffix
ttemp = trng1;
do {
c = input.charAt(cidx);
if (c == separator) {
return null;
}
if (tokens[ttemp] != c) {
ttemp = trng1;
masks[cidx] = c;
} else {
ttemp++;
}
cidx++;
} while (ttemp < trng2 && cidx < clen);
if (ttemp < trng2) {
return null;
}
tidx = trng2;
}
} else {
for (; cidx < clen; cidx++) {
c = input.charAt(cidx);
if (c == separator) {
break;
}
masks[cidx] = c;
}
tidx++;
}
} else if (types[tidx] == WildcardPattern.STAR_STAR_TYPE) {
if (separator != Character.MIN_VALUE) {
trng1 = -1;
trng2 = -1;
for (ttemp = tidx + 1; ttemp < tlen; ttemp++) {
if (trng1 == -1) {
if (types[ttemp] == WildcardPattern.LITERAL_TYPE) {
trng1 = ttemp;
}
} else {
if (types[ttemp] != WildcardPattern.LITERAL_TYPE) {
trng2 = ttemp - 1;
break;
}
}
}
if (trng1 > -1 && trng2 > -1) {
crng2 = cidx;
ttemp = trng1;
while (ttemp <= trng2 && crng2 < clen) {
c = input.charAt(crng2);
if (c != tokens[ttemp]) {
ttemp = trng1;
masks[crng2] = c;
} else {
ttemp++;
}
crng2++;
}
if (ttemp <= trng2) {
tidx = trng2;
if (cidx > 0) {
cidx--;
masks[cidx] = 0; //erase
}
} else {
cidx = crng2;
tidx = trng2 + 1;
}
} else {
tidx++;
scnt1 = 0;
for (ttemp = tidx; ttemp < tlen; ttemp++) {
if (types[ttemp] == WildcardPattern.SEPARATOR_TYPE) {
scnt1++;
}
}
if (scnt1 > 0) {
crng1 = cidx;
crng2 = clen;
scnt2 = 0;
while (crng2 > 0 && crng1 <= crng2--) {
if (input.charAt(crng2) == separator) {
scnt2++;
}
if (scnt1 == scnt2) {
break;
}
}
if (scnt1 == scnt2) {
cidx = crng2;
for (ctmp = crng1; ctmp < crng2; ctmp++) {
masks[ctmp] = input.charAt(ctmp);
}
}
} else {
for (; cidx < clen; cidx++) {
masks[cidx] = input.charAt(cidx);
}
}
}
} else {
for (ctmp = cidx; ctmp < clen; ctmp++) {
masks[ctmp] = input.charAt(ctmp);
}
cidx = clen; //complete
tidx++;
}
} else if (types[tidx] == WildcardPattern.QUESTION_TYPE) {
if (tidx > tlen - 1
|| types[tidx + 1] != WildcardPattern.LITERAL_TYPE
|| tokens[tidx + 1] != input.charAt(cidx)) {
if (separator != Character.MIN_VALUE) {
if (input.charAt(cidx) != separator) {
masks[cidx] = input.charAt(cidx);
cidx++;
}
} else {
masks[cidx] = input.charAt(cidx);
cidx++;
}
}
tidx++;
} else if (types[tidx] == WildcardPattern.PLUS_TYPE) {
if (separator != Character.MIN_VALUE) {
if (input.charAt(cidx) == separator) {
return null;
}
}
masks[cidx] = input.charAt(cidx);
cidx++;
tidx++;
} else if (types[tidx] == WildcardPattern.SEPARATOR_TYPE) {
if (tokens[tidx] != input.charAt(cidx)) {
return null;
}
if (tidx > 0 && cidx > 0 && masks[cidx - 1] > 0
&& (types[tidx - 1] == WildcardPattern.STAR_STAR_TYPE
|| types[tidx - 1] == WildcardPattern.STAR_TYPE)) {
masks[cidx] = input.charAt(cidx);
}
tidx++;
cidx++;
} else if (types[tidx] == WildcardPattern.EOT_TYPE) {
break;
} else {
tidx++;
}
}
if (cidx < clen) {
if (cidx == 0 && tlen > 0 && types[0] == WildcardPattern.STAR_STAR_TYPE) {
for (int end = 0; end < clen; end++) {
if (input.charAt(end) != separator) {
if (end > 0) {
return input.subSequence(end, clen).toString();
}
break;
}
}
return input.toString();
}
return null;
}
if (tidx < tlen) {
for (ttemp = tidx; ttemp < tlen; ttemp++) {
if (types[ttemp] == WildcardPattern.LITERAL_TYPE
|| types[ttemp] == WildcardPattern.PLUS_TYPE
|| types[ttemp] == WildcardPattern.SEPARATOR_TYPE) {
return null;
}
}
}
StringBuilder sb = new StringBuilder(masks.length);
for (char mask : masks) {
if (mask > 0) {
sb.append(mask);
}
}
if (types[0] == WildcardPattern.STAR_STAR_TYPE || types[0] == WildcardPattern.STAR_TYPE) {
for (int end = 0; end < sb.length(); end++) {
if (sb.charAt(end) != separator) {
if (end > 0) {
sb.delete(0, end);
}
break;
}
}
}
return sb.toString();
}
}