<commit_before>/**
 * Copyright (C) 2010 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;
import org.dom4j.QName;
import org.orbeon.oxf.common.OXFException;
import org.orbeon.oxf.common.Version;
import org.orbeon.oxf.pipeline.api.ExternalContext;
import org.orbeon.oxf.pipeline.api.PipelineContext;
import org.orbeon.oxf.processor.*;
import org.orbeon.oxf.properties.Properties;
import org.orbeon.oxf.servlet.OrbeonXFormsFilter;
import org.orbeon.oxf.xml.dom4j.Dom4jUtils;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Utility class to rewrite URLs.
 */
public class URLRewriterUtils {

    // Versioned resources configuration
    public static final String RESOURCES_VERSIONED_PROPERTY = "oxf.resources.versioned";
    public static final boolean RESOURCES_VERSIONED_DEFAULT = false;
    public static final boolean WSRP_ENCODE_RESOURCES_DEFAULT = false;

    private static final String REWRITING_PLATFORM_PATHS_PROPERTY = "oxf.url-rewriting.platform-paths";
    private static final String REWRITING_APP_PATHS_PROPERTY = "oxf.url-rewriting.app-paths";
    private static final String REWRITING_APP_PREFIX_PROPERTY = "oxf.url-rewriting.app-prefix";
    private static final String REWRITING_STRATEGY_PROPERTY_PREFIX = "oxf.url-rewriting.strategy.";
    private static final String REWRITING_CONTEXT_PROPERTY_PREFIX = "oxf.url-rewriting.";
    private static final String REWRITING_CONTEXT_PROPERTY_SUFFIX = ".context";
    private static final String REWRITING_WSRP_ENCODE_RESOURCES_PROPERTY = "oxf.url-rewriting.wsrp.encode-resources";

    public static final String RESOURCES_VERSION_NUMBER_PROPERTY = "oxf.resources.version-number";

    public static final String REWRITING_SERVICE_BASE_URI_PROPERTY = "oxf.url-rewriting.service.base-uri";
    public static final String REWRITING_SERVICE_BASE_URI_DEFAULT = "";

    public static final List<PathMatcher> EMPTY_PATH_MATCHER_LIST = Collections.emptyList();

    private static final PathMatcher MATCH_ALL_PATH_MATCHER;
    public static final List<URLRewriterUtils.PathMatcher> MATCH_ALL_PATH_MATCHERS;

    static {
        MATCH_ALL_PATH_MATCHER = new URLRewriterUtils.PathMatcher("/*", null, null, true);
        MATCH_ALL_PATH_MATCHERS = Collections.singletonList(URLRewriterUtils.MATCH_ALL_PATH_MATCHER);
    }

    /**
     * Rewrite a URL based on the request URL, a URL, and a rewriting mode.
     *
     * @param request       incoming request
     * @param urlString     URL to rewrite
     * @param rewriteMode   rewrite mode (see ExternalContext.Response)
     * @return              rewritten URL
     */
    public static String rewriteURL(ExternalContext.Request request, String urlString, int rewriteMode) {
        return rewriteURL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getClientContextPath(urlString),
                request.getRequestPath(), urlString, rewriteMode);
    }

    /**
     * Rewrite a service URL. The URL is rewritten against a base URL which is:
     *
     * o specified externally or
     * o the incoming request if not specified externally
     *
     * @param request           incoming request
     * @param urlString         URL to rewrite
     * @param rewriteMode       rewrite mode
     * @return                  rewritten URL
     */
    public static String rewriteServiceURL(ExternalContext.Request request, String urlString, int rewriteMode) {

        assert (rewriteMode & ExternalContext.Response.REWRITE_MODE_ABSOLUTE) != 0;

        final String baseURIProperty = getServiceBaseURI();
        if (StringUtils.isBlank(baseURIProperty)) {
            // Property not specified, use request to build base URI
            return rewriteURL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getClientContextPath(urlString),
                    request.getRequestPath(), urlString, rewriteMode);
        } else {
            // Property specified
            try {
                final URI baseURI = new URI(baseURIProperty.trim());
                // NOTE: Force absolute URL to be returned in this case anyway
                return rewriteURL(baseURI.getScheme() != null ? baseURI.getScheme() : request.getScheme(),
                        baseURI.getHost() != null ? baseURI.getHost() : request.getServerName(),
                        baseURI.getHost() != null ? baseURI.getPort() : request.getServerPort(),
                        baseURI.getPath(), "", urlString, rewriteMode);

            } catch (URISyntaxException e) {
                throw new OXFException("Incorrect base URI property specified: " + baseURIProperty);
            }
        }
    }

    /**
     * Return a context path as seen by the client. This might be the current request's context path, or the forwarding
     * servlet's context path. The returned path might be different for Orbeon resources vs. application resources.<commit_msg>Don't attempt to rewrite absolute service URL<commit_after>/**
 * Copyright (C) 2010 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;
import org.dom4j.QName;
import org.orbeon.oxf.common.OXFException;
import org.orbeon.oxf.common.Version;
import org.orbeon.oxf.pipeline.api.ExternalContext;
import org.orbeon.oxf.pipeline.api.PipelineContext;
import org.orbeon.oxf.processor.*;
import org.orbeon.oxf.properties.Properties;
import org.orbeon.oxf.servlet.OrbeonXFormsFilter;
import org.orbeon.oxf.xml.dom4j.Dom4jUtils;

import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Utility class to rewrite URLs.
 */
public class URLRewriterUtils {

    // Versioned resources configuration
    public static final String RESOURCES_VERSIONED_PROPERTY = "oxf.resources.versioned";
    public static final boolean RESOURCES_VERSIONED_DEFAULT = false;
    public static final boolean WSRP_ENCODE_RESOURCES_DEFAULT = false;

    private static final String REWRITING_PLATFORM_PATHS_PROPERTY = "oxf.url-rewriting.platform-paths";
    private static final String REWRITING_APP_PATHS_PROPERTY = "oxf.url-rewriting.app-paths";
    private static final String REWRITING_APP_PREFIX_PROPERTY = "oxf.url-rewriting.app-prefix";
    private static final String REWRITING_STRATEGY_PROPERTY_PREFIX = "oxf.url-rewriting.strategy.";
    private static final String REWRITING_CONTEXT_PROPERTY_PREFIX = "oxf.url-rewriting.";
    private static final String REWRITING_CONTEXT_PROPERTY_SUFFIX = ".context";
    private static final String REWRITING_WSRP_ENCODE_RESOURCES_PROPERTY = "oxf.url-rewriting.wsrp.encode-resources";

    public static final String RESOURCES_VERSION_NUMBER_PROPERTY = "oxf.resources.version-number";

    public static final String REWRITING_SERVICE_BASE_URI_PROPERTY = "oxf.url-rewriting.service.base-uri";
    public static final String REWRITING_SERVICE_BASE_URI_DEFAULT = "";

    public static final List<PathMatcher> EMPTY_PATH_MATCHER_LIST = Collections.emptyList();

    private static final PathMatcher MATCH_ALL_PATH_MATCHER;
    public static final List<URLRewriterUtils.PathMatcher> MATCH_ALL_PATH_MATCHERS;

    static {
        MATCH_ALL_PATH_MATCHER = new URLRewriterUtils.PathMatcher("/*", null, null, true);
        MATCH_ALL_PATH_MATCHERS = Collections.singletonList(URLRewriterUtils.MATCH_ALL_PATH_MATCHER);
    }

    /**
     * Rewrite a URL based on the request URL, a URL, and a rewriting mode.
     *
     * @param request       incoming request
     * @param urlString     URL to rewrite
     * @param rewriteMode   rewrite mode (see ExternalContext.Response)
     * @return              rewritten URL
     */
    public static String rewriteURL(ExternalContext.Request request, String urlString, int rewriteMode) {
        return rewriteURL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getClientContextPath(urlString),
                request.getRequestPath(), urlString, rewriteMode);
    }

    /**
     * Rewrite a service URL. The URL is rewritten against a base URL which is:
     *
     * o specified externally or
     * o the incoming request if not specified externally
     *
     * @param request           incoming request
     * @param urlString         URL to rewrite
     * @param rewriteMode       rewrite mode
     * @return                  rewritten URL
     */
    public static String rewriteServiceURL(ExternalContext.Request request, String urlString, int rewriteMode) {

        assert (rewriteMode & ExternalContext.Response.REWRITE_MODE_ABSOLUTE) != 0;

        // Case where a protocol is specified: the URL is left untouched
        if (NetUtils.urlHasProtocol(urlString))
            return urlString;

        final String baseURIProperty = getServiceBaseURI();
        if (StringUtils.isBlank(baseURIProperty)) {
            // Property not specified, use request to build base URI
            return rewriteURL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getClientContextPath(urlString),
                    request.getRequestPath(), urlString, rewriteMode);
        } else {
            // Property specified
            try {
                final URI baseURI = new URI(baseURIProperty.trim());
                // NOTE: Force absolute URL to be returned in this case anyway
                return rewriteURL(baseURI.getScheme() != null ? baseURI.getScheme() : request.getScheme(),
                        baseURI.getHost() != null ? baseURI.getHost() : request.getServerName(),
                        baseURI.getHost() != null ? baseURI.getPort() : request.getServerPort(),
                        baseURI.getPath(), "", urlString, rewriteMode);

            } catch (URISyntaxException e) {
                throw new OXFException("Incorrect base URI property specified: " + baseURIProperty);
            }
        }
    }

    /**
     * Return a context path as seen by the client. This might be the current request's context path, or the forwarding
     * servlet's context path. The returned path might be different for Orbeon resources vs. application resources.
{'fraction_non_alphanumeric': 0.08072601555747623, 'fraction_numerical': 0.0019014693171996544, 'mean_word_length': 3.3288439955106623, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '129696', 'n_tokens_mistral': 3289, 'n_tokens_neox': 3149, 'n_words': 930}