use of grails.web.mapping.exceptions.UrlMappingException in project grails-core by grails.
the class RegexUrlMapping method createURLInternal.
@SuppressWarnings({ "unchecked" })
private String createURLInternal(Map paramValues, String encoding, boolean includeContextPath) {
if (encoding == null)
encoding = "utf-8";
String contextPath = "";
if (includeContextPath) {
GrailsWebRequest webRequest = (GrailsWebRequest) RequestContextHolder.getRequestAttributes();
if (webRequest != null) {
contextPath = webRequest.getContextPath();
}
}
if (paramValues == null)
paramValues = Collections.emptyMap();
StringBuilder uri = new StringBuilder(contextPath);
Set usedParams = new HashSet();
String[] tokens = urlData.getTokens();
int paramIndex = 0;
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
if (i == tokens.length - 1 && urlData.hasOptionalExtension()) {
token += OPTIONAL_EXTENSION_WILDCARD;
}
Matcher m = OPTIONAL_EXTENSION_WILDCARD_PATTERN.matcher(token);
if (m.find()) {
boolean tokenSet = false;
if (token.startsWith(CAPTURED_WILDCARD)) {
ConstrainedProperty prop = constraints[paramIndex++];
String propName = prop.getPropertyName();
Object value = paramValues.get(propName);
usedParams.add(propName);
if (value != null) {
token = token.replaceFirst(DOUBLE_WILDCARD_PATTERN.pattern(), Matcher.quoteReplacement(value.toString()));
tokenSet = true;
} else {
token = token.replaceFirst(DOUBLE_WILDCARD_PATTERN.pattern(), "");
}
} else {
tokenSet = true;
}
if (tokenSet) {
uri.append(SLASH);
}
ConstrainedProperty prop = constraints[paramIndex++];
String propName = prop.getPropertyName();
Object value = paramValues.get(propName);
usedParams.add(propName);
if (value != null) {
String ext = "." + value;
uri.append(token.replace(OPTIONAL_EXTENSION_WILDCARD + '?', ext).replace(OPTIONAL_EXTENSION_WILDCARD, ext));
} else {
uri.append(token.replace(OPTIONAL_EXTENSION_WILDCARD + '?', "").replace(OPTIONAL_EXTENSION_WILDCARD, ""));
}
continue;
}
if (token.endsWith("?")) {
token = token.substring(0, token.length() - 1);
}
m = DOUBLE_WILDCARD_PATTERN.matcher(token);
if (m.find()) {
StringBuffer buf = new StringBuffer();
do {
ConstrainedProperty prop = constraints[paramIndex++];
String propName = prop.getPropertyName();
Object value = paramValues.get(propName);
usedParams.add(propName);
if (value == null && !prop.isNullable()) {
throw new UrlMappingException("Unable to create URL for mapping [" + this + "] and parameters [" + paramValues + "]. Parameter [" + prop.getPropertyName() + "] is required, but was not specified!");
} else if (value == null) {
m.appendReplacement(buf, "");
} else {
m.appendReplacement(buf, Matcher.quoteReplacement(value.toString()));
}
} while (m.find());
m.appendTail(buf);
try {
String v = buf.toString();
if (v.indexOf(SLASH) > -1 && CAPTURED_DOUBLE_WILDCARD.equals(token)) {
// individually URL encode path segments
if (v.startsWith(SLASH)) {
// get rid of leading slash
v = v.substring(SLASH.length());
}
String[] segs = v.split(SLASH);
for (String segment : segs) {
uri.append(SLASH).append(encode(segment, encoding));
}
} else if (v.length() > 0) {
// original behavior
uri.append(SLASH).append(encode(v, encoding));
} else {
// Stop processing tokens once we hit an empty one.
break;
}
} catch (UnsupportedEncodingException e) {
throw new ControllerExecutionException("Error creating URL for parameters [" + paramValues + "], problem encoding URL part [" + buf + "]: " + e.getMessage(), e);
}
} else {
uri.append(SLASH).append(token);
}
}
populateParameterList(paramValues, encoding, uri, usedParams);
if (LOG.isDebugEnabled()) {
LOG.debug("Created reverse URL mapping [" + uri.toString() + "] for parameters [" + paramValues + "]");
}
return uri.toString();
}
use of grails.web.mapping.exceptions.UrlMappingException in project grails-core by grails.
the class RegexUrlMapping method convertToRegex.
/**
* Converts a Grails URL provides via the UrlMappingData interface to a regular expression.
*
* @param url The URL to convert
* @return A regex Pattern objet
*/
protected Pattern convertToRegex(String url) {
Pattern regex;
String pattern = null;
try {
// Escape any characters that have special meaning in regular expressions,
// such as '.' and '+'.
pattern = url.replace(".", "\\.");
pattern = pattern.replace("+", "\\+");
int lastSlash = pattern.lastIndexOf('/');
String urlRoot = lastSlash > -1 ? pattern.substring(0, lastSlash) : pattern;
String urlEnd = lastSlash > -1 ? pattern.substring(lastSlash, pattern.length()) : "";
// Now replace "*" with "[^/]" and "**" with ".*".
pattern = "^" + urlRoot.replace("(\\.(*))", "(\\.[^/]+)?").replaceAll("([^\\*])\\*([^\\*])", "$1[^/]+?$2").replaceAll("([^\\*])\\*$", "$1[^/]+?").replaceAll("\\*\\*", ".*");
if ("/(*)(\\.(*))".equals(urlEnd)) {
// shortcut this common special case which will
// happen any time a URL mapping ends with a pattern like
// /$someVariable(.$someExtension)
pattern += "/([^/]+)\\.([^/.]+)?";
} else {
pattern += urlEnd.replace("(\\.(*))", "(\\.[^/]+)?").replaceAll("([^\\*])\\*([^\\*])", "$1[^/]+?$2").replaceAll("([^\\*])\\*$", "$1[^/]+?").replaceAll("\\*\\*", ".*").replaceAll("\\(\\[\\^\\/\\]\\+\\)\\\\\\.", "([^/.]+?)\\\\.").replaceAll("\\(\\[\\^\\/\\]\\+\\)\\?\\\\\\.", "([^/.]+?)\\?\\\\.");
}
pattern += "/??$";
regex = Pattern.compile(pattern);
} catch (PatternSyntaxException pse) {
throw new UrlMappingException("Error evaluating mapping for pattern [" + pattern + "] from Grails URL mappings: " + pse.getMessage(), pse);
}
return regex;
}
use of grails.web.mapping.exceptions.UrlMappingException in project grails-core by grails.
the class DefaultUrlMappingEvaluator method evaluateMappings.
@SuppressWarnings({ "unchecked", "rawtypes" })
public List<UrlMapping> evaluateMappings(Class theClass) {
GroovyObject obj = (GroovyObject) BeanUtils.instantiateClass(theClass);
if (obj instanceof Script) {
Script script = (Script) obj;
Binding b = new Binding();
MappingCapturingClosure closure = new MappingCapturingClosure(script);
b.setVariable("mappings", closure);
script.setBinding(b);
script.run();
Closure mappings = closure.getMappings();
Binding binding = script.getBinding();
return evaluateMappings(script, mappings, binding);
}
throw new UrlMappingException("Unable to configure URL mappings for class [" + theClass + "]. A URL mapping must be an instance of groovy.lang.Script.");
}
Aggregations