package org.jboss.seam.web; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; public class IncomingPattern { String view; String pattern; ServletMapping viewMapping; java.util.regex.Pattern regexp; List<String> regexpArgs = new ArrayList<String>(); public IncomingPattern(ServletMapping viewMapping, String view, String pattern) { this.view = view; this.pattern = pattern; this.viewMapping = viewMapping; parsePattern(pattern); } public Rewrite rewrite(String path) { return new IncomingRewrite(path); } public void parsePattern(String value) { StringBuffer expr = new StringBuffer(); expr.append("^"); while (value.length()>0) { int pos = value.indexOf('{'); if (pos == -1) { expr.append(regexpLiteral(value)); value = ""; } else { int pos2 = value.indexOf('}'); if (pos2 == -1) { throw new IllegalArgumentException("invalid pattern"); } expr.append(regexpLiteral(value.substring(0,pos))); String arg = value.substring(pos+1,pos2); expr.append(regexpArg(arg)); regexpArgs.add(arg); value = value.substring(pos2+1); } } expr.append("$"); regexp = java.util.regex.Pattern.compile(expr.toString()); } private String regexpArg(String substring) { return "([^/]*)"; } private String regexpLiteral(String value) { StringBuffer res = new StringBuffer(); for (int i=0; i<value.length(); i++) { char c = value.charAt(i); if (Character.isLetterOrDigit(c)) { res.append(c); } else { res.append('\\').append(c); } } return res.toString(); } public class IncomingRewrite implements Rewrite { String incoming; String queryArgs; Boolean isMatch = null; private List<String> matchedArgs = new ArrayList<String>(); public IncomingRewrite(String incoming) { int queryPos = incoming.indexOf('?'); if (queryPos == -1) { this.incoming = incoming; this.queryArgs = ""; } else { this.incoming = incoming.substring(0, queryPos); this.queryArgs = incoming.substring(queryPos+1); } // don't match trailing slash - it might indicate an empty arg // this.incoming = stripTrailingSlash(this.incoming); } // private String stripTrailingSlash(String text) { // if (text.endsWith("/")) { // return stripTrailingSlash(text.substring(0,text.length()-1)); // } // return text; // } public boolean isMatch() { if (isMatch == null) { isMatch = match(); } return isMatch; } protected boolean match() { if (incoming==null) { return false; } Matcher matcher = regexp.matcher(incoming); if (matcher.find()) { for (int i=0; i<regexpArgs.size(); i++) { matchedArgs.add(matcher.group(i+1)); } return true; } return false; } public String rewrite() { StringBuffer result = new StringBuffer(); result.append(mappedURL(view)); boolean first = true; if (queryArgs.length()>0) { result.append('?').append(queryArgs); first = false; } for (int i=0; i<regexpArgs.size(); i++) { String key = regexpArgs.get(i); String value = matchedArgs.get(i); if (first) { result.append('?'); first = false; } else { result.append('&'); } result.append(key).append('=').append(value); } return result.toString(); } } private String mappedURL(String viewId) { return viewMapping.mapViewIdToURL(viewId); } }