package railo.runtime.rest.path;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import railo.runtime.type.Struct;
public class ExpressionPath extends Path {
private Pattern pattern;
private List<String> variables;
public ExpressionPath(Pattern pattern, List<String> variables) {
this.pattern=pattern;
this.variables=variables;
}
public static Path getInstance(String path) {
/*
TODO handle if a pattern already has defined a group
*/
int last=-1,startIndex,endIndex=0,index;
String content,variableName,regexPart;
StringBuilder regex=new StringBuilder();
List<String> variables=new ArrayList<String>();
while((startIndex=path.indexOf('{',last))!=-1){
if(last+1<startIndex) {
delimiter(variables,regex,path.substring(last+1,startIndex));
}
endIndex=path.indexOf('}',startIndex+1);
if(endIndex==-1) return new LiteralPath(path);
content=path.substring(startIndex+1,endIndex);
index=content.indexOf(':');
if(index!=-1) {
variableName=content.substring(0,index).trim();
regexPart=content.substring(index+1).trim();
}
else {
variableName=content.trim();
regexPart=".+";
}
regex.append('(');
regex.append(regexPart);
regex.append(')');
variables.add(variableName);
//print.e(variableName);
//print.e(regexPart);
last=endIndex;
}
if(endIndex+1<path.length())
delimiter(variables,regex,path.substring(endIndex+1));
//regex.append("(.*)");
Pattern pattern=Pattern.compile(regex.toString());
//print.e(regex);
//print.e(variables);
return new ExpressionPath(pattern,variables);
}
private static void delimiter(List<String> variables, StringBuilder regex, String delimiter) {
variables.add(null);
regex.append('(');
/*print.e(delimiter+":"+Pattern.quote(delimiter));
StringBuilder sb=new StringBuilder();
int len=delimiter.length();
char c;
for (int i=0; i<len; i++) {
c=delimiter.charAt(i);
switch(c){
case '.': sb.append("\\.");break;
case '?': sb.append("\\?");break;
case '\\': sb.append("\\\\");break;
case '^': sb.append("\\^");break;
case '$': sb.append("\\$");break;
case '+': sb.append("\\+");break;
default: sb.append(c);
break;
}
}*/
regex.append(Pattern.quote(delimiter));
regex.append(')');
}
@Override
public boolean match(Struct result,String path) {
String var;
Matcher m = pattern.matcher(path);
boolean hasMatches=m.find();
if(!hasMatches) return false;
if (hasMatches) {
// Get all groups for this match
int len=m.groupCount();
for (int i=1; i<=len; i++) {
String groupStr = m.group(i);
var = variables.get(i-1);
if(var!=null) result.setEL(var, groupStr.trim());
}
}
return true;
}
/*public static void main(String[] args) {
Path path = getInstance("{aaa : \\d+}-{b}");
print.e("+++++++++++");
Map<String,String> res=new HashMap<String, String>();
print.e(path.match(res,"1234-cd"));
print.e(res);
}*/
public String toString(){
return "expression:"+pattern.pattern();
}
}