private String createURLInternal()

in grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/RegexUrlMapping.java [285:412]


    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();
    }