All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aspectran.core.util.wildcard.WildcardPattern Maven / Gradle / Ivy

There is a newer version: 8.1.5
Show newest version
/*
 * 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;

import java.util.Objects;

/**
 * The Class WildcardPattern.
 * 

* The following standard quantifiers are recognized: *

*
{@code *}
matches single character
*
{@code +}
matches one or more characters
*
{@code ?}
matches zero or more characters
*
{@code **}
matches zero or more string delimited by separators
*
{@code \}
Wildcard characters can be escaped
*
*

* Examples *

*
/static/{@code *}
/static/a.jpg
*
/static{@code *}/{@code **}/b/{@code *}
matches one or more characters
*
/static{@code *}/{@code **}
/static/a/a.jpg
*
{@code **}/static/{@code **}
a/b/static/a/b/c/a.jpg
*
/static-{@code ?}/a{@code ?}{@code ?}.jpg
/static-a/abc.jpg
*
*/ public class WildcardPattern { private static final char ESCAPE_CHAR = '\\'; private static final char SPACE_CHAR = ' '; public static final char STAR_CHAR = '*'; public static final char QUESTION_CHAR = '?'; public static final char PLUS_CHAR = '+'; static final int LITERAL_TYPE = 1; static final int STAR_TYPE = 2; static final int STAR_STAR_TYPE = 3; static final int QUESTION_TYPE = 4; static final int PLUS_TYPE = 5; static final int SKIP_TYPE = 8; static final int SEPARATOR_TYPE = 9; static final int EOT_TYPE = 0; private final String patternString; private final char separator; private final char[] tokens; private final int[] types; private final float weight; public WildcardPattern(String patternString) { this(patternString, Character.MIN_VALUE); } public WildcardPattern(String patternString, char separator) { this.patternString = patternString; this.separator = separator; this.tokens = patternString.toCharArray(); this.types = new int[tokens.length]; this.weight = parse(); } private float parse() { boolean star = false; boolean esc = false; int ptype = SKIP_TYPE; int pindex = 0; for (int i = 0; i < tokens.length; i++) { if (tokens[i] == STAR_CHAR) { if (esc) { esc = false; } else { if (star) { types[i - 1] = SKIP_TYPE; types[i] = STAR_STAR_TYPE; // type 2: double star star = false; } else { types[i] = STAR_TYPE; // type 1: star star = true; } } if (ptype == QUESTION_TYPE && types[i] == STAR_TYPE) { types[pindex] = SKIP_TYPE; } } else if (tokens[i] == QUESTION_CHAR) { if (esc) { types[i - 1] = SKIP_TYPE; esc = false; } else { types[i] = QUESTION_TYPE; // type 3: question } if (ptype == STAR_TYPE && types[i] == QUESTION_TYPE) { types[i] = SKIP_TYPE; } } else if (tokens[i] == PLUS_CHAR) { if (esc) { types[i - 1] = SKIP_TYPE; esc = false; } else { types[i] = PLUS_TYPE; // type 4: plus } if (ptype == STAR_TYPE && types[i] == PLUS_CHAR) { types[i] = SKIP_TYPE; } } else if (tokens[i] == separator) { // Separator character not escaped esc = false; types[i] = SEPARATOR_TYPE; // type 9: separator } else if (tokens[i] == ESCAPE_CHAR) { types[i] = SKIP_TYPE; esc = true; } else { if (esc) { types[i - 1] = LITERAL_TYPE; } else { types[i] = LITERAL_TYPE; } } if (tokens[i] != STAR_CHAR && star) { star = false; } if (types[i] != SKIP_TYPE) { ptype = types[i]; pindex = i; } } for (int i = 0, s = 0; i < tokens.length; i++) { if (types[i] == SKIP_TYPE) { s++; tokens[i] = SPACE_CHAR; types[i] = EOT_TYPE; } else if (s > 0) { tokens[i - s] = tokens[i]; types[i - s] = types[i]; tokens[i] = SPACE_CHAR; types[i] = EOT_TYPE; } } float weight = 0.0f; for (int i = 0; i < types.length; i++) { if (types[i] == EOT_TYPE) { break; } weight += ((i + 1) * types[i] / 10f); } return weight; } public char getSeparator() { return separator; } protected char[] getTokens() { return tokens; } protected int[] getTypes() { return types; } public float getWeight() { return weight; } /** * If the pattern matches then returns true. * @param compareString the compare string * @return true, if successful */ public boolean matches(String compareString) { return WildcardMatcher.matches(this, compareString); } /** * Erase the characters that corresponds to the wildcard, and * returns collect only the remaining characters. * In other words, only it remains for the wildcard character. * @param nakedString the naked string * @return the masked string */ public String mask(String nakedString) { return WildcardMasker.mask(this, nakedString); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof WildcardPattern)) { return false; } WildcardPattern wp = (WildcardPattern)obj; return (Objects.equals(wp.toString(), patternString) && Objects.equals(wp.getSeparator(), getSeparator())); } @Override public int hashCode() { int result = this.patternString.hashCode(); result = 31 * result + separator; return result; } @Override public String toString() { return patternString; } public static WildcardPattern compile(String patternString) { return new WildcardPattern(patternString); } public static WildcardPattern compile(String patternString, char separator) { return new WildcardPattern(patternString, separator); } public static boolean hasWildcards(String str) { char[] ca = str.toCharArray(); for (char c : ca) { if (c == STAR_CHAR || c == QUESTION_CHAR || c == PLUS_CHAR) { return true; } } return false; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy