001 package railo.runtime.rest.path; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 import java.util.regex.Matcher; 006 import java.util.regex.Pattern; 007 008 import railo.runtime.type.Struct; 009 010 011 public class ExpressionPath extends Path { 012 013 private Pattern pattern; 014 private List<String> variables; 015 016 public ExpressionPath(Pattern pattern, List<String> variables) { 017 this.pattern=pattern; 018 this.variables=variables; 019 } 020 021 public static Path getInstance(String path) { 022 /* 023 TODO handle if a pattern already has defined a group 024 */ 025 026 int last=-1,startIndex,endIndex=0,index; 027 String content,variableName,regexPart; 028 StringBuilder regex=new StringBuilder(); 029 List<String> variables=new ArrayList<String>(); 030 while((startIndex=path.indexOf('{',last))!=-1){ 031 if(last+1<startIndex) { 032 delimiter(variables,regex,path.substring(last+1,startIndex)); 033 } 034 035 endIndex=path.indexOf('}',startIndex+1); 036 if(endIndex==-1) return new LiteralPath(path); 037 038 content=path.substring(startIndex+1,endIndex); 039 index=content.indexOf(':'); 040 if(index!=-1) { 041 variableName=content.substring(0,index).trim(); 042 regexPart=content.substring(index+1).trim(); 043 } 044 else { 045 variableName=content.trim(); 046 regexPart=".+"; 047 } 048 regex.append('('); 049 regex.append(regexPart); 050 regex.append(')'); 051 variables.add(variableName); 052 //print.e(variableName); 053 //print.e(regexPart); 054 last=endIndex; 055 } 056 057 if(endIndex+1<path.length()) 058 delimiter(variables,regex,path.substring(endIndex+1)); 059 060 //regex.append("(.*)"); 061 062 Pattern pattern=Pattern.compile(regex.toString()); 063 //print.e(regex); 064 //print.e(variables); 065 return new ExpressionPath(pattern,variables); 066 } 067 068 069 private static void delimiter(List<String> variables, StringBuilder regex, String delimiter) { 070 variables.add(null); 071 regex.append('('); 072 /*print.e(delimiter+":"+Pattern.quote(delimiter)); 073 StringBuilder sb=new StringBuilder(); 074 int len=delimiter.length(); 075 char c; 076 for (int i=0; i<len; i++) { 077 c=delimiter.charAt(i); 078 switch(c){ 079 case '.': sb.append("\\.");break; 080 case '?': sb.append("\\?");break; 081 case '\\': sb.append("\\\\");break; 082 case '^': sb.append("\\^");break; 083 case '$': sb.append("\\$");break; 084 case '+': sb.append("\\+");break; 085 default: sb.append(c); 086 break; 087 } 088 }*/ 089 090 regex.append(Pattern.quote(delimiter)); 091 regex.append(')'); 092 } 093 094 @Override 095 public boolean match(Struct result,String path) { 096 String var; 097 Matcher m = pattern.matcher(path); 098 boolean hasMatches=m.find(); 099 if(!hasMatches) return false; 100 101 if (hasMatches) { 102 // Get all groups for this match 103 int len=m.groupCount(); 104 for (int i=1; i<=len; i++) { 105 String groupStr = m.group(i); 106 var = variables.get(i-1); 107 if(var!=null) result.setEL(var, groupStr.trim()); 108 } 109 } 110 111 return true; 112 } 113 114 /*public static void main(String[] args) { 115 Path path = getInstance("{aaa : \\d+}-{b}"); 116 print.e("+++++++++++"); 117 Map<String,String> res=new HashMap<String, String>(); 118 print.e(path.match(res,"1234-cd")); 119 print.e(res); 120 }*/ 121 122 123 124 public String toString(){ 125 return "expression:"+pattern.pattern(); 126 } 127 }