![JAR search and dependency download from the Maven repository](/logo.png)
org.apache.juneau.objecttools.StringMatcherFactory Maven / Gradle / Ivy
// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file *
// * to you 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 org.apache.juneau.objecttools;
import static org.apache.juneau.common.internal.StringUtils.*;
import java.util.*;
import java.util.regex.*;
import org.apache.juneau.*;
import org.apache.juneau.common.internal.*;
/**
* String matcher factory for the {@link ObjectSearcher} class.
*
*
* The class provides searching based on the following patterns:
*
*
* "property=foo" - Simple full word match
* "property=fo*" , "property=?ar" - Meta-character matching
* "property=foo bar" (implicit), "property=^foo ^bar" (explicit) - Multiple OR'ed patterns
* "property=+fo* +*ar" - Multiple AND'ed patterns
* "property=fo* -bar" - Negative patterns
* "property='foo bar'" - Patterns with whitespace
* "property=foo\\'bar" - Patterns with single-quotes
* "property=/foo\\s+bar" - Regular expression match
*
*
* See Also:
*/
public class StringMatcherFactory extends MatcherFactory {
/**
* Default reusable matcher.
*/
public static final StringMatcherFactory DEFAULT = new StringMatcherFactory();
@Override
public boolean canMatch(ClassMeta> cm) {
return true;
}
@Override
public AbstractMatcher create(String pattern) {
return new StringMatcher(pattern);
}
/**
* A construct representing a single search pattern.
*/
private static class StringMatcher extends AbstractMatcher {
private String pattern;
private static final AsciiSet
META_CHARS = AsciiSet.create("*?'\""),
SQ_CHAR = AsciiSet.create("'"),
DQ_CHAR = AsciiSet.create("\""),
REGEX_CHARS = AsciiSet.create("+\\[]{}()^$.");
Pattern[] orPatterns, andPatterns, notPatterns;
public StringMatcher(String searchPattern) {
this.pattern = searchPattern.trim();
List ors = new LinkedList<>();
List ands = new LinkedList<>();
List nots = new LinkedList<>();
for (String s : splitQuoted(pattern, true)) {
char c0 = s.charAt(0), c9 = s.charAt(s.length()-1);
if (c0 == '/' && c9 == '/' && s.length() > 1) {
ands.add(Pattern.compile(strip(s)));
} else {
char prefix = '^';
boolean ignoreCase = false;
if (s.length() > 1 && (c0 == '^' || c0 == '+' || c0 == '-')) {
prefix = c0;
s = s.substring(1);
c0 = s.charAt(0);
}
if (c0 == '\'') {
s = unEscapeChars(strip(s), SQ_CHAR);
ignoreCase = true;
} else if (c0 == '"') {
s = unEscapeChars(strip(s), DQ_CHAR);
}
if (REGEX_CHARS.contains(s) || META_CHARS.contains(s)) {
StringBuilder sb = new StringBuilder();
boolean isInEscape = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (isInEscape) {
if (c == '?' || c == '*' || c == '\\')
sb.append('\\').append(c);
else
sb.append(c);
isInEscape = false;
} else {
if (c == '\\')
isInEscape = true;
else if (c == '?')
sb.append(".?");
else if (c == '*')
sb.append(".*");
else if (REGEX_CHARS.contains(c))
sb.append("\\").append(c);
else
sb.append(c);
}
}
s = sb.toString();
}
int flags = Pattern.DOTALL;
if (ignoreCase)
flags |= Pattern.CASE_INSENSITIVE;
Pattern p = Pattern.compile(s, flags);
if (prefix == '-')
nots.add(p);
else if (prefix == '+')
ands.add(p);
else
ors.add(p);
}
}
orPatterns = ors.toArray(new Pattern[ors.size()]);
andPatterns = ands.toArray(new Pattern[ands.size()]);
notPatterns = nots.toArray(new Pattern[nots.size()]);
}
@Override
public boolean matches(ClassMeta> cm, Object o) {
String s = (String)o;
for (Pattern andPattern : andPatterns)
if (! andPattern.matcher(s).matches())
return false;
for (Pattern notPattern : notPatterns)
if (notPattern.matcher(s).matches())
return false;
for (Pattern orPattern : orPatterns)
if (orPattern.matcher(s).matches())
return true;
return orPatterns.length == 0;
}
@Override
public String toString() {
return pattern;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy