if (pattern == null)
return null;
// make sure it starts with /
if (pattern == null || pattern.length() < 1 || !pattern.startsWith("/")) {
throw new ParseException(pattern, "A URL binding must begin with /");
}
// parse the pattern
String path = null;
List<Object> components = new ArrayList<Object>();
boolean brace = false, escape = false;
char[] chars = pattern.toCharArray();
StringBuilder buf = new StringBuilder(pattern.length());
char c = 0;
for (int i = 0; i < chars.length; i++) {
c = chars[i];
if (!escape) {
switch (c) {
case '{':
if (!brace) {
brace = true;
if (path == null) {
// extract trailing non-alphanum chars as a literal to trim the path
int end = buf.length() - 1;
while (end >= 0 && !Character.isJavaIdentifierPart(buf.charAt(end)))
--end;
if (end < 0) {
path = buf.toString();
}
else {
++end;
path = buf.substring(0, end);
components.add(buf.substring(end));
}
}
else {
components.add(buf.toString());
}
buf.setLength(0);
continue;
}
break;
case '}':
if (brace) {
brace = false;
components.add(parseUrlBindingParameter(beanType, buf.toString()));
buf.setLength(0);
continue;
}
break;
case '\\':
escape = true;
// Preserve escape characters for parameter name parser
if (brace) {
buf.append(c);
}
continue;
}
}
// append the char
buf.append(c);
escape = false;
}
// Were we led to expect more characters?
if (escape)
throw new ParseException(pattern, "Expression must not end with escape character");
else if (brace)
throw new ParseException(pattern, "Unterminated left brace ('{') in expression");
// handle whatever is left
if (buf.length() > 0) {
if (path == null)
path = buf.toString();