![JAR search and dependency download from the Maven repository](/logo.png)
io.github.lab515.utils.ClassMatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qray Show documentation
Show all versions of qray Show documentation
remoting ondemand in java
package io.github.lab515.utils;
import java.util.ArrayList;
import java.util.List;
/**
* Class Matcher replace regex to match class
* **.Aclass*.**
*/
public class ClassMatcher {
private String[][] segsArray = null; // array of segment array, each segment array matches one expression
private int[][] segFlagsArray = null;
private Integer[] posNegArray = null; // indicate the pos | seg of every expression
private char sp = '.';
private int max = 0;
private boolean negAll = true;
private boolean posAll = true;
private static final int T_ALL = 1, T_PART = 2, T_HEADING = 4, T_CONST = 0,T_TAILING = 8, T_TH = 12; // easier implementation
public ClassMatcher(String[] strings) {
this(strings, '.');
}
/**
* Constructor
*
* @param exps expression array. Rule is same with Ant. Starts with "-" for un-match and "+" for match.
* @param splitter package splitter
*/
public ClassMatcher(String[] exps, char splitter) {
sp = splitter;
if (exps != null && exps.length > 0) {
List segsList = new ArrayList(); // list of segments, each of which are for each expression
List segsFlags = new ArrayList();
List posNegList = new ArrayList(); // indicate the pos | seg of every expression
String[] segArray = null;
int[] flags = null;
char c = ' ';
for (String exp : exps) {
if (exp == null){
exp = "";
}
else{
exp = exp.trim();
}
if (exp.startsWith("-")) {
posNegList.add(0);
exp = exp.substring(1);
posAll = false;
} else {
if (exp.startsWith("+")) {
exp = exp.substring(1);
}
posNegList.add(1);
negAll = false;
}
segsList.add(segArray = parseExp(exp,splitter));
flags = new int[segArray.length];
segsFlags.add(flags);
int cnt = 0;
for(int i = 0; i < flags.length;i++){
exp = segArray[i];
if(exp == null){
segArray[cnt++] = null; // set it
break; // reach the end;
}
else{
c = exp.charAt(0);
if(c == '*'){
flags[cnt] = T_ALL;
segArray[cnt++] = exp;
}
else if(c == '+'){
flags[cnt] = T_PART;
segArray[cnt++] = exp;
} else{
if(c == sp && cnt> 0 && (flags[cnt-1] & T_ALL) != 0) {
flags[cnt - 1] |= T_HEADING;
exp = exp.substring(1);
}
if(exp.length() > 0 && exp.charAt(exp.length()-1) == sp && i< flags.length-1 && segArray[i+1] != null && segArray[i+1].charAt(0) == '*'){
exp = exp.substring(0,exp.length()-1);
if(exp.length() > 0){
segArray[cnt] = exp;
flags[cnt++] = T_CONST;
}
segArray[cnt] = "*";
flags[cnt++] = T_ALL | T_TAILING;
i++;
}else if(exp.length() > 0){
segArray[cnt] = exp;
flags[cnt++] = T_CONST;
}
}
}
}
if (cnt > max) {
max = cnt;
}
}
if (segsList.size() > 0) {
segsArray = new String[segsList.size()][];
posNegArray = new Integer[segsList.size()];
segFlagsArray = new int[segsList.size()][];
segsList.toArray(segsArray);
posNegList.toArray(posNegArray);
segsFlags.toArray(segFlagsArray);
segsList.clear();
posNegList.clear();
}
}
}
private static String[] parseExp(String exp, char sp) {
if (exp == null || (exp = exp.trim()).length() < 1) {
return new String[]{null};
}
if (exp.endsWith("*")) {
exp += " "; // to process exp == '*'
}
String[] segs = exp.split("\\*");
if (segs.length < 2) { // no '*' in the exp or only *
segs[0] = segs[0].trim();
return segs;
}
List segList = new ArrayList();
String last = null;
String seg = segs[0].trim();
if (seg.length() > 0) { // segs[0].length == 0 means start with '*', then last == null
last = seg;
segList.add(last);
}
for (int i = 1; i < segs.length; i++) {
seg = segs[i];
// log.info "seg " + i + ":" + seg + ", last:" + last
if (last == null || (last.charAt(0) != '*' && last.charAt(0) != '+')) {
// optimize: **.** equals **
if (!(seg.length() == 0 && last != null && last.length() == 1 && last.charAt(0) == sp
&& segList.size() > 1 && segList.get(segList.size() - 2).charAt(0) == '*')) {
last = seg.length() == 0 ? "*" : "+";
segList.add(last);
} else {
segList.remove(segList.size() - 1);
last = "*";
}
}
seg = seg.trim();
if (seg.length() > 0) { // ignore space between '*', like "* *"
last = seg;
segList.add(last);
}
}
segs = new String[segList.size() + 1];
segList.toArray(segs);
segList.clear();
return segs;
}
public boolean matchSingle(String cls) {
if (segsArray == null || cls == null) {
return false;
}
int[] idx = new int[max];
boolean matched = false;
for (int i = 0; i < segsArray.length; i++) {
if (matchClassInternal(segsArray[i], idx, segFlagsArray[i], cls)) {
if (posNegArray[i] > 0) {
if (posAll) {
return true;
}
matched = true;
} else {
return false;
}
}
}
return matched || negAll;
}
public String[] match(String[] clses) {
if (segsArray == null || clses == null) {
return null;
}
int[] idx = new int[max];
ArrayList ret = new ArrayList();
int i = 0;
int l = segsArray.length;
boolean matched = false;
for (String cls : clses) {
if (cls == null) {
continue;
}
matched = false;
for (i = 0; i < l; i++) {
if (matchClassInternal(segsArray[i], idx,segFlagsArray[i], cls)) {
if (posNegArray[i] < 1 || posAll) {
if (posAll) {
ret.add(cls);
}
break;
}
matched = true;
}
}
if (i >= l && (matched || negAll)) {
ret.add(cls);
}
}
String[] r = null;
if (ret.size() > 0) {
r = new String[ret.size()];
ret.toArray(r);
ret.clear();
}
return r;
}
public String[] match(List clses) {
if (segsArray == null || clses == null) {
return null;
}
int[] idx = new int[max];
ArrayList ret = new ArrayList();
int i = 0;
int l = segsArray.length;
boolean matched = false;
for (String cls : clses) {
if (cls == null) {
continue;
}
matched = false;
for (i = 0; i < l; i++) {
if (matchClassInternal(segsArray[i], idx,segFlagsArray[i], cls)) {
if (posNegArray[i] < 1 || posAll) {
if (posAll) {
ret.add(cls);
}
break;
}
matched = true;
}
}
if (i >= l && (matched || negAll)) {
ret.add(cls);
}
}
String[] r = null;
if (ret.size() > 0) {
r = new String[ret.size()];
ret.toArray(r);
ret.clear();
}
return r;
}
private boolean matchClassInternal(String[] segs, int[] segIdx, int[] segFlags, String cls) {
int stac = 0;
int pos = 0;
String seg = null;
int lastPos = 0;
int clen = cls.length();
int flag = 0;
int prePos = 0;
int slen = 0;
for(int i=0; i < segIdx.length;i++){segIdx[i] = -1;}
while (stac >= 0 && stac < segs.length) {
if(lastPos < pos) {// check if we need to fix the gap
if(stac < 1){
return false;
}
stac--;
lastPos = segIdx[stac]; // prePos <= lastPos < pos
flag = segFlags[stac];
seg = segs[stac];
if(flag == T_CONST){ // apparently not a match, and the cosnt must be after this at least
pos = cls.indexOf(seg, pos - seg.length()); // may need to find a way to optimize the search
segIdx[stac] = pos;
if(pos < 0){
return false;
}
}else if(flag == T_PART){
prePos = pos;
pos = cls.lastIndexOf(sp,pos-1);
if(pos < 0){
pos = 0;
}else {
pos++;
}
if(pos < lastPos){
pos = lastPos;
}else{
segIdx[stac] = pos;
}
if(lastPos == pos){
lastPos = pos = prePos;
stac++;
}
}else {
if((flag & T_HEADING) != 0){
pos = cls.indexOf(sp,pos-1);
if(pos < 0){
pos = clen;
}
if(pos < clen){
pos++;
}
}
lastPos = pos; // direct match
stac++;
}
}else{
seg = segs[stac];
if(seg == null){
pos = clen;
if(lastPos == pos){
break;
}
continue;
}
flag = segFlags[stac];
slen = 0;
if (flag == T_CONST) {
if(pos >= clen){
return false;
}
prePos = segIdx[stac];
if(prePos >= pos) {
pos = prePos;
}else {
pos = cls.indexOf(seg, pos);
if (pos < 0){
return false;
}
}
slen = seg.length();
} else if(flag != T_PART && flag != T_ALL) {
// .**/**./.**. three conditions
flag &= T_TH;
prePos = pos;
if(!((prePos == 0 && flag == T_HEADING) || (prePos == clen && flag == T_TAILING))){
prePos = prePos < clen ? cls.indexOf(sp,prePos) : -1;
if(prePos < 0){
if((flag & T_HEADING) != 0){
return false;
}
prePos = clen;
}
}
if(flag == T_HEADING) {
segIdx[stac] = lastPos;
slen = prePos - pos;
if(pos < clen && (pos > 0 || cls.charAt(pos) == sp)){
slen++;
}
}else {
pos = prePos;
if(pos < clen){
slen = 1; // must be
}
}
}
if(lastPos == pos){
segIdx[stac++] = pos;
pos += slen;
lastPos = pos;
}
}
}
return lastPos == pos && pos == clen;
}
public static String[] matchClasses(String[] exprs, String[] clses) {
return matchClasses(exprs, clses, '.');
}
public static String[] matchClasses(String exprs, String[] clses) {
return matchClasses(exprs, clses, '.');
}
public static String[] matchClasses(String exprs, String[] clses, char clsSplitter) {
if (exprs == null || clses == null) {
return null;
}
return matchClasses(exprs.split("\n"), clses, clsSplitter);
}
public static String[] matchClasses(String[] exprs, String[] clses, char clsSplitter) {
if (exprs == null || clses == null) {
return null;
}
ClassMatcher m = new ClassMatcher(exprs, clsSplitter);
return m.match(clses);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy