Search in sources :

Example 1 with UrlMappingException

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();
}
Also used : Matcher(java.util.regex.Matcher) UnsupportedEncodingException(java.io.UnsupportedEncodingException) UrlMappingException(grails.web.mapping.exceptions.UrlMappingException) ControllerExecutionException(org.grails.web.servlet.mvc.exceptions.ControllerExecutionException) GrailsWebRequest(org.grails.web.servlet.mvc.GrailsWebRequest) ConstrainedProperty(grails.gorm.validation.ConstrainedProperty)

Example 2 with UrlMappingException

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;
}
Also used : UrlMappingException(grails.web.mapping.exceptions.UrlMappingException) Pattern(java.util.regex.Pattern) PatternSyntaxException(java.util.regex.PatternSyntaxException)

Example 3 with UrlMappingException

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.");
}
Also used : Binding(groovy.lang.Binding) UrlMappingException(grails.web.mapping.exceptions.UrlMappingException) Script(groovy.lang.Script) Closure(groovy.lang.Closure) GroovyObject(groovy.lang.GroovyObject)

Aggregations

UrlMappingException (grails.web.mapping.exceptions.UrlMappingException)3 ConstrainedProperty (grails.gorm.validation.ConstrainedProperty)1 Binding (groovy.lang.Binding)1 Closure (groovy.lang.Closure)1 GroovyObject (groovy.lang.GroovyObject)1 Script (groovy.lang.Script)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 PatternSyntaxException (java.util.regex.PatternSyntaxException)1 GrailsWebRequest (org.grails.web.servlet.mvc.GrailsWebRequest)1 ControllerExecutionException (org.grails.web.servlet.mvc.exceptions.ControllerExecutionException)1