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    }