Class SlingUrl

  • All Implemented Interfaces:
    Cloneable

    public class SlingUrl
    extends Object
    implements Cloneable
    A Sling URL parser / builder class supporting the Sling URL decomposition (and composition / modification by using the builder methods) and provides builder methods to change e.g. selectors and extension, but can also represent other URL types. It is meant to represent every user input without failing - if it's not a known URL scheme and thus cannot be parsed it'll just return the input unchanged, and the modification methods fail silently.

    Major usecases

    Building URLs for resources

    With the constructors with a Resource parameter, e.g. SlingUrl(SlingHttpServletRequest, Resource), it's possible to generate an URL and give it some selectors(String), extension(String) or and suffix(Resource) and parameter(String, String...). If only the path of the resource is known, that'd start with SlingUrl(SlingHttpServletRequest) and initalized with fromPath(String).

    Modifying userspecified URLs

    The class is meant to represent all types of URL (including invalid ones), and parse them in a do-what-I-mean fashion, so that they can be modified according to Sling rules, as far as possible. There are direct constructors from a Resource, and various ways to initialize it mit a method starting with from (e.g. fromPathOrUrl(String)) after creating a basic builder with SlingUrl(SlingHttpServletRequest) or SlingUrl(SlingHttpServletRequest, LinkMapper).

    Caution: this does not consider the resource tree to parse URLs from String form, so there will be cases where this differs from ResourceResolver.resolve(HttpServletRequest, String) : e.g. we consider in /foo/a.b/bar/c.d the /bar/c.d as suffix, while this might be different in reality!

    See Also:
    "https://sling.apache.org/documentation/the-sling-engine/url-decomposition.html", "https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/URI.html"
    • Field Detail

      • SCHEME_PATTERN

        protected static final Pattern SCHEME_PATTERN
      • HTTP_SCHEME_PATTERN

        protected static final Pattern HTTP_SCHEME_PATTERN
      • FILE_SCHEME_PATTERN

        protected static final Pattern FILE_SCHEME_PATTERN
      • USERNAMEPASSWORD

        protected static final Pattern USERNAMEPASSWORD
      • HTTP_URL_PATTERN

        protected static final Pattern HTTP_URL_PATTERN
        Regex matching various variants of Sling-URLs.

        Debug regex e.g. with http://www.softlion.com/webtools/regexptest/ .

      • FILE_URL_PATTERN

        protected static final Pattern FILE_URL_PATTERN
      • ABSOLUTE_PATH_PATTERN

        protected static final Pattern ABSOLUTE_PATH_PATTERN
      • RELATIVE_PATH_PATTERN

        protected static final Pattern RELATIVE_PATH_PATTERN
      • HTTP_SCHEME

        protected static final Pattern HTTP_SCHEME
      • FILE_SCHEME

        protected static final Pattern FILE_SCHEME
      • SPECIAL_SCHEME

        protected static final Pattern SPECIAL_SCHEME
      • scheme

        protected String scheme
        The scheme of the URL. To be able to represent protocol-relative URL, we distinguish here null and the empty string: null is no scheme, empty string is a protocol-relative URL (e.g. //www/something.css).
      • username

        protected String username
      • password

        protected String password
      • contextPath

        protected String contextPath
      • path

        protected String path
        Contains the path inclusive leading and trailing / , not the file/resource itself: for /a/b/c it's /a/b/ . Emptly for relative paths / unparseable stuff.
      • selectors

        protected final List<String> selectors
      • extension

        protected String extension
      • suffix

        protected String suffix
      • fragment

        protected String fragment
      • resourcePath

        protected transient String resourcePath
      • resource

        protected transient org.apache.sling.api.resource.Resource resource
      • request

        protected final org.apache.sling.api.SlingHttpServletRequest request
      • linkMapper

        protected final LinkMapper linkMapper
    • Constructor Detail

      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource,
                        @Nullable
                        @Nullable String extension)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource,
                        @Nullable
                        @Nullable String selectors,
                        @Nullable
                        @Nullable String extension)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource,
                        @Nullable
                        @Nullable String selectors,
                        @Nullable
                        @Nullable String extension,
                        @Nullable
                        @Nullable String suffix)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource,
                        @Nullable
                        @Nullable String selectors,
                        @Nullable
                        @Nullable String extension,
                        @Nullable
                        @Nullable String suffix,
                        @Nullable
                        @Nullable String parameterString)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @NotNull
                        @NotNull org.apache.sling.api.resource.Resource resource,
                        @Nullable
                        @Nullable String selectors,
                        @Nullable
                        @Nullable String extension,
                        @Nullable
                        @Nullable String suffix,
                        @Nullable
                        @Nullable String parameterString,
                        boolean decodeParameters,
                        @Nullable
                        @Nullable LinkMapper linkMapper)
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        @Nullable
                        @Nullable LinkMapper linkMapper)
        Constructs a yet invalid SlingUrl that has to be initialized with one of the from* methods. A linkmapper can be given if the url is a path.
      • SlingUrl

        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request)
        Constructs a yet invalid SlingUrl that has to be initialized with one of the from* methods.
      • SlingUrl

        @Deprecated
        public SlingUrl​(@NotNull
                        @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                        String url)
        Deprecated.
        use new SlingUrl(request).fromUrl(url)
    • Method Detail

      • fromUrl

        @NotNull
        public @NotNull SlingUrl fromUrl​(@NotNull
                                         @NotNull String url)
        Parses the url. Caution: if the url contains several periods like e.g. http://host/a.b/c.d/suffix , this might parse it wrong, since we'd have to consult the resource tree to determine whether the resource path is /a or /a.b/c . Caution 2: This applies URL-decoding that replaces percent encoded characters (%[0-9a-fA-F][0-9a-fA-F]) by their decoded counterparts before saving the URL (except if it'll be of type SlingUrl.UrlType.OTHER, where we don't touch anything). If there are characters outside the URL range (say, the user types an url http://www/päth) these are left untouched for now. When the URL is reconstructed in getUrl(), such characters are encoded (to http://www/p%C3A4th). This might however lead to some rare trouble when there is something in there that looks like a percent encoded character but isn't meant as such, e.g. '%effect', but that won't work right in a browser, too.
        Returns:
        this for builder style chaining
      • fromUrl

        @NotNull
        public @NotNull SlingUrl fromUrl​(@NotNull
                                         @NotNull String url,
                                         boolean decode)
        Parses the url, possibly URL-decoding it when decode = true. Caution: if the url contains several periods like e.g. http://host/a.b/c.d/suffix , this might parse it wrong, since we'd have to consult the resource tree to determine whether the resource path is /a or /a.b/c .
      • fromUri

        public SlingUrl fromUri​(@NotNull
                                @NotNull URI uri)
        Assigns from the given uri, trying to parse extension and suffix from it. This avoids any issues with character encoding and broken URLs. Caution: if the url contains several periods like e.g. http://host/a.b/c.d/suffix , this * might parse it wrong, since we'd have to consult the resource tree to determine whether the resource path * is /a or /a.b/c .
      • fromPathOrUrl

        public SlingUrl fromPathOrUrl​(@NotNull
                                      @NotNull String pathOrUrl,
                                      boolean decode)
        Initializes from an url or an absolute resource path, possibly URL-decoding it when decode = true. If pathOrUrl starts with a single slash, this is the same as fromPath(String), otherwise the same as fromUrl(String, boolean).
        Returns:
        this for builder style chaining
      • fromPathOrUrl

        public SlingUrl fromPathOrUrl​(@NotNull
                                      @NotNull String pathOrUrl)
        Initializes from an url or an absolute resource path. If pathOrUrl starts with a single slash, this is the same as fromPath(String), otherwise the same as fromUrl(String).
        Returns:
        this for builder style chaining
      • isAbsolutePath

        protected boolean isAbsolutePath​(String pathOrUrl)
      • fromPath

        @NotNull
        public @NotNull SlingUrl fromPath​(@NotNull
                                          @NotNull String resourcePath)
        Initializes the SlingUrl from a resource path, absolute or relative.
        Parameters:
        resourcePath - an absolute or relative path
        Returns:
        this for builder style chaining
      • fromRequest

        @NotNull
        public @NotNull SlingUrl fromRequest​(javax.servlet.http.HttpServletRequest request)
        Initialzes the SlingUrl from a requests URL
        Parameters:
        request - the HTTP request to use
        Returns:
        this for builder style chaining
      • getRequest

        @NotNull
        public @NotNull org.apache.sling.api.SlingHttpServletRequest getRequest()
      • isExternal

        public boolean isExternal()
        An external URL: we assume it's external when a scheme is set.
      • getResourcePath

        @Nullable
        public @Nullable String getResourcePath()
        For internal urls the path to the rendered resource. The path to getResource() if that exists.
      • getResource

        @Nullable
        public @Nullable org.apache.sling.api.resource.Resource getResource()
        For internal urls: if this is a path to a resource, this returns it (suffix, selectors and parameters ignored, if present).
      • getContextPath

        @Nullable
        public @Nullable String getContextPath()
        If an internal path starts with the HttpServletRequest.getContextPath(), this contains the context path, and the context path is removed from getPathAndName().
      • getPathAndName

        @NotNull
        public @NotNull String getPathAndName()
        The path to the file including the filename, but not the extension, selectors etc.
      • getPathAndNameExt

        @NotNull
        public @NotNull String getPathAndNameExt()
        The path to the file including the filename and the extension, but no selectors.
      • setPathAndNameExt

        public SlingUrl setPathAndNameExt​(@Nullable
                                          @Nullable String fullpath)
        Sets the path, name and extension from the given e.g. resource path. Caution: if the fullpath contains several periods, the result can be different than you expect and broken.
        Returns:
        this for builder style chaining
      • setPathAndName

        public SlingUrl setPathAndName​(@Nullable
                                       @Nullable String fullpath)
        Sets the path and name from the given e.g. resource path, but does not touch the getExtension(). Alias for setResourcePath(String)
        Parameters:
        fullpath - the path and filename to be set. We do not check for periods in there.
        Returns:
        this for builder style chaining
      • setResourcePath

        public SlingUrl setResourcePath​(@Nullable
                                        @Nullable String resourcePath)
        Sets the resource path encoded in the URL to the given path. This touches path and getName(), but not selectors and extension, works also when the resource path contains periods.
        Parameters:
        resourcePath - an absolute or possibly relative path. We do not check for periods in there.
        Returns:
        this for builder style chaining
      • resourcePath

        public SlingUrl resourcePath​(@Nullable
                                     @Nullable String resourcePath)
        Sets the resource path encoded in the URL to the given path. This touches path and getName(), but not selectors and extension, works also when the resource path contains periods. Alias for setResourcePath(String).
        Parameters:
        resourcePath - an absolute or possibly relative path. We do not check for periods in there.
        Returns:
        this for builder style chaining
      • selector

        public SlingUrl selector​(@Nullable
                                 @Nullable String... value)
      • addSelector

        public SlingUrl addSelector​(@Nullable
                                    @Nullable String... value)
      • selectors

        public SlingUrl selectors​(@Nullable
                                  @Nullable String selectors)
      • setSelectors

        public SlingUrl setSelectors​(@Nullable
                                     @Nullable String selectors)
        Sets the selectors to the given string - can contain multiple selectors separated with period.
      • removeSelector

        public SlingUrl removeSelector​(String... value)
      • clearSelectors

        public SlingUrl clearSelectors()
      • getExtension

        @Nullable
        public @Nullable String getExtension()
      • extension

        public SlingUrl extension​(@Nullable
                                  @Nullable String extension)
      • setExtension

        public SlingUrl setExtension​(@Nullable
                                     @Nullable String extension)
      • getSuffix

        @Nullable
        public @Nullable String getSuffix()
      • suffix

        public SlingUrl suffix​(@Nullable
                               @Nullable org.apache.sling.api.resource.Resource resource)
      • suffix

        public SlingUrl suffix​(@Nullable
                               @Nullable org.apache.sling.api.resource.Resource resource,
                               @Nullable
                               @Nullable String extension)
      • suffix

        public SlingUrl suffix​(@Nullable
                               @Nullable String suffix)
      • setSuffix

        public SlingUrl setSuffix​(@Nullable
                                  @Nullable String suffix)
      • getParameter

        @Nullable
        public @Nullable String getParameter​(@NotNull
                                             @NotNull String name)
        Returns:
        the first value of the parameter values if values are present; an empty string if the value list is empty (parameter present but without a value); null if the parameter is not present
      • getParameterValues

        @Nullable
        public @Nullable List<String> getParameterValues​(@NotNull
                                                         @NotNull String name)
        Returns:
        an unmodifiable List of the parameter values if present
      • getParameters

        @NotNull
        public @NotNull Map<String,​List<String>> getParameters()
        Unmodifiable map of the contained parameters.

        This is unmodifiable since otherwise we would have to trust the user to call clearTransients() on every change.

      • addParameters

        public SlingUrl addParameters​(String parameterString,
                                      boolean decode)
        Adds parameters parsed from an HTTP query string.
      • setParameters

        public SlingUrl setParameters​(String parameterString,
                                      boolean decode)
      • clearParameters

        public SlingUrl clearParameters()
      • getFragment

        @Nullable
        public @Nullable String getFragment()
        The fragment part of the URL. Caution: this isn't available on all types.
      • setFragment

        @NotNull
        public @NotNull SlingUrl setFragment​(@Nullable
                                             @Nullable String fragment)
        Sets the fragment. Caution: this isn't available on all types. Same as fragment(String).
        Returns:
        this for builder style chaining
      • fragment

        @NotNull
        public @NotNull SlingUrl fragment​(@Nullable
                                          @Nullable String fragment)
        Sets the fragment part of the URL. Caution: this isn't available on all types. Same as setFragment(String).
        Returns:
        this for builder style chaining
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class Object
      • getUrl

        public String getUrl()
        Builds the URL from its parts saved in the builder.
      • clearTransients

        protected void clearTransients()
        Internal reset method for the calculated transient values like the URL, called when anything changes.
      • getScheme

        @Nullable
        public @Nullable String getScheme()
        The scheme part of an URL. Caution: this isn't available on all types. To be able to represent protocol-relative URL, we distinguish here null and the empty string: null is no scheme applicable, as in SlingUrl.UrlType.RELATIVE, empty string is a protocol-relative URL (e.g. //www/something.css).
      • setScheme

        @NotNull
        public @NotNull SlingUrl setScheme​(@Nullable
                                           @Nullable String scheme)
        Sets the scheme. Caution: this isn't available on all types. To be able to represent protocol-relative URL, we distinguish here null and the empty string: null is no scheme, empty string is a protocol-relative URL (e.g. //www/something.css). Same as scheme(String).
        Returns:
        this for builder style chaining
      • scheme

        @NotNull
        public @NotNull SlingUrl scheme​(@Nullable
                                        @Nullable String scheme)
        Sets the scheme part of an URL. Caution: this isn't available on all types. Same as setScheme(String).
        Returns:
        this for builder style chaining
      • getUsername

        @Nullable
        public @Nullable String getUsername()
        The username part of an URL. Caution: this isn't available on all types.
      • setUsername

        @NotNull
        public @NotNull SlingUrl setUsername​(@Nullable
                                             @Nullable String username)
        Sets the username. Caution: this isn't available on all types. Same as username(String).
        Returns:
        this for builder style chaining
      • username

        @NotNull
        public @NotNull SlingUrl username​(@Nullable
                                          @Nullable String username)
        Sets the username part of an URL. Caution: this isn't available on all types. Same as setUsername(String).
        Returns:
        this for builder style chaining
      • getPassword

        @Nullable
        public @Nullable String getPassword()
        The password part of an URL. Caution: this isn't available on all types.
      • setPassword

        @NotNull
        public @NotNull SlingUrl setPassword​(@Nullable
                                             @Nullable String password)
        Sets the password. Caution: this isn't available on all types. Same as password(String).
        Returns:
        this for builder style chaining
      • password

        @NotNull
        public @NotNull SlingUrl password​(@Nullable
                                          @Nullable String password)
        Sets the password part of an URL. Caution: this isn't available on all types. Same as setPassword(String).
        Returns:
        this for builder style chaining
      • getHost

        @Nullable
        public @Nullable String getHost()
        The host part of the URL. Caution: this isn't available on all types.
      • setHost

        @NotNull
        public @NotNull SlingUrl setHost​(@Nullable
                                         @Nullable String host)
        Sets the host part of the URL. Caution: this isn't available on all types. Same as host(String).
        Returns:
        this for builder style chaining
      • host

        @NotNull
        public @NotNull SlingUrl host​(@Nullable
                                      @Nullable String host)
        Sets the host part of the URL. Caution: this isn't available on all types. Same as setHost(String).
        Returns:
        this for builder style chaining
      • getPort

        @Nullable
        public @Nullable Integer getPort()
        The port part of the URL. Caution: this isn't available on all types.
      • setPort

        @NotNull
        public @NotNull SlingUrl setPort​(@Nullable
                                         @Nullable Integer port)
        Sets the port. Caution: this isn't available on all types. Same as port(Integer).
        Returns:
        this for builder style chaining
      • port

        @NotNull
        public @NotNull SlingUrl port​(@Nullable
                                      @Nullable Integer port)
        Sets the port part of the URL. Caution: this isn't available on all types. Same as setPort(Integer).
        Returns:
        this for builder style chaining
      • getType

        @NotNull
        public @NotNull SlingUrl.UrlType getType()
        The type of the URL. Caution: this isn't available on all types.
      • setType

        @NotNull
        public @NotNull SlingUrl setType​(@NotNull
                                         @NotNull SlingUrl.UrlType type)
        Sets the type. Caution: this isn't available on all types. Same as type(UrlType).
        Returns:
        this for builder style chaining
      • type

        @NotNull
        public @NotNull SlingUrl type​(@NotNull
                                      @NotNull SlingUrl.UrlType type)
        Sets the type of the URL. Caution: this isn't available on all types. Same as setType(UrlType).
        Returns:
        this for builder style chaining
      • getName

        @Nullable
        public @Nullable String getName()
        The filename; in case of type OTHER this contains the whole URL but the scheme and colon. Caution: this isn't available on all types.
      • setName

        @NotNull
        public @NotNull SlingUrl setName​(@Nullable
                                         @Nullable String name)
        Sets the name. Caution: this isn't available on all types. Same as name(String).
        Returns:
        this for builder style chaining
      • name

        @NotNull
        public @NotNull SlingUrl name​(@Nullable
                                      @Nullable String name)
        Sets the filename; in case of type OTHER this contains the whole URL but the scheme and colon. Caution: this isn't available on all types. Same as setName(String).
        Returns:
        this for builder style chaining
      • reset

        public void reset()
      • buildUrl

        protected String buildUrl()
      • assignFromGroups

        protected void assignFromGroups​(Matcher matcher,
                                        boolean decode,
                                        boolean hostAndPort)
      • decode

        protected String decode​(String value,
                                boolean decode)
      • parseParameters

        protected void parseParameters​(@NotNull
                                       @NotNull String parameterString,
                                       boolean decode)
      • getLinkMapper

        protected static LinkMapper getLinkMapper​(@NotNull
                                                  @NotNull org.apache.sling.api.SlingHttpServletRequest request,
                                                  @Nullable
                                                  @Nullable LinkMapper linkMapper)
      • toDebugString

        public String toDebugString()
        Lists the internal parse results - mainly for debugging purposes.