package sk.nociar.jpacloner.graphs;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WildcardPattern extends GraphExplorer {
private static final Pattern p = Pattern.compile("\\*|\\?|[^\\*\\?]+");
private static final Map<String, WildcardPattern> cache = new HashMap<String, WildcardPattern>();
private final Pattern pattern;
private final ConcurrentMap<String, Boolean> isMatched = new ConcurrentHashMap<String, Boolean>();
private WildcardPattern(String s) {
StringBuilder sb = new StringBuilder("^");
Matcher m = p.matcher(s);
while (m.find()) {
String token = m.group();
if ("?".equals(token)) {
sb.append(".");
} else if ("*".equals(token)) {
sb.append(".*?"); // Reluctant quantifier
} else {
sb.append(Pattern.quote(token));
}
}
sb.append("$");
pattern = Pattern.compile(sb.toString());
}
public static synchronized WildcardPattern get(String s) {
WildcardPattern wildcardPattern = cache.get(s);
if (wildcardPattern == null) {
wildcardPattern = new WildcardPattern(s);
cache.put(s, wildcardPattern);
}
return wildcardPattern;
}
@Override
public Set<?> explore(Collection<?> entities, EntityExplorer entityExplorer) {
Set<Object> explored = new HashSet<Object>();
for (Object entity : entities) {
for (String property : entityExplorer.getProperties(entity)) {
Boolean matches = isMatched.get(property);
if (matches == null) {
matches = pattern.matcher(property).matches();
isMatched.put(property, matches);
}
if (matches) {
Collection<?> value = entityExplorer.explore(entity, property);
if (value != null) {
explored.addAll(value);
}
}
}
}
return explored;
}
}