All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dankito.utils.web.UrlUtil.kt Maven / Gradle / Ivy

The newest version!
package net.dankito.utils.web

import java.net.URI


open class UrlUtil {

    companion object {
        const val HttpRegexPattern = "http[s]?://"
        val HttpRegex = Regex(HttpRegexPattern, RegexOption.IGNORE_CASE)
    }


    open fun isUri(string: String): Boolean {
        try {
            val uri = URI.create(string)
            return uri != null && uri.scheme != null
        } catch(ignored: Exception) { } // ok, sharedText is not an Uri

        return false
    }

    /**
     * Returns true if parameter is a valid uri and scheme is either 'http' or 'https'.
     */
    open fun isHttpUri(string: String): Boolean {
        try {
            val uri = URI.create(string)
            return uri != null && (uri.scheme.equals("http", true) || uri.scheme.equals("https", true))
        } catch(ignored: Exception) { } // ok, sharedText is not an Uri

        return false
    }

    /**
     * Tries to extract an uri from string that starts with 'http://' or 'https://' case insensitive.
     */
    open fun extractHttpUri(string: String): String? {
        HttpRegex.find(string)?.let { matchResult ->
            val range = matchResult.range
            val startIndex = range.start

            var endIndex = string.indexOf(' ', startIndex)
            if (endIndex < 0) { // string ends with uri
                endIndex = string.length
            }

            return string.substring(startIndex, endIndex)
        }

        return null
    }


    open fun getHostName(url: String): String? {
        var host = url.substringAfter("://").substringBefore('/') // as fallback if parsing URI doesn't work

        try {
            val uri = URI.create(url)
            host = uri.host
        } catch(e: Exception) { }


        host = tryToRemoveDomainUrlAndWWW(host)

        return host
    }

    protected open fun tryToRemoveDomainUrlAndWWW(host: String): String {
        try {
            val lastIndexOfDot = host.lastIndexOf('.')

            if(lastIndexOfDot > 0) {
                var nextIndexOfDot = host.lastIndexOf('.', lastIndexOfDot - 1)

                if(nextIndexOfDot >= lastIndexOfDot - 4) { // e.g. domains like .co.uk, ...
                    nextIndexOfDot = host.lastIndexOf('.', nextIndexOfDot - 1)
                }

                if(nextIndexOfDot > -1) {
                    return host.substring(nextIndexOfDot + 1)
                }
            }
        } catch(e: Exception) { }

        return host
    }


    open fun getFileName(url: String): String {
        try {
            val uri = URI(url)
            val path = uri.path

            return path.substringAfterLast('/')
        } catch(e: Exception) { }

        return url.substringAfterLast('/').substringBefore('?')
    }


    open fun makeLinkAbsolute(url: String, siteUrl: String): String {
        var absoluteUrl = url

        if(url.startsWith("//")) {
            if(siteUrl.startsWith("https:")) {
                absoluteUrl = "https:" + url
            }
            else {
                absoluteUrl = "http:" + url
            }
        }
        else if(url.startsWith("/")) {
            tryToMakeUrlAbsolute(url, siteUrl)?.let { absoluteUrl = it }
        }
        else if(url.startsWith("http") == false) {
            // url does not start with '/' (we checked above) -> prepend '/' so that resolving url works
            tryToMakeUrlAbsolute("/" + url, siteUrl)?.let { absoluteUrl = it }
        }

        return absoluteUrl
    }

    protected open fun tryToMakeUrlAbsolute(relativeUrl: String, siteUrl: String): String? {
        try {
            val relativeUri = URI(relativeUrl)
            if(relativeUri.isAbsolute && relativeUri.scheme.startsWith("http") == false) {
                return relativeUrl // it's an absolute uri but just doesn't start with http, e.g. mailto: for file:
            }
        } catch(ignored: Exception) { }

        try {
            val uri = URI(siteUrl)
            return uri.resolve(relativeUrl).toString()
        } catch(ignored: Exception) { }

        try {
            val uri = URI(siteUrl)

            val port = if(uri.port > 0) ":" + uri.port else ""
            val separator = if(relativeUrl.startsWith("/")) "" else "/"

            val manuallyCreatedUriString = uri.scheme + "://" + uri.host + port + separator + relativeUrl
            val manuallyCreatedUri = URI(manuallyCreatedUriString)
            return manuallyCreatedUri.toString()
        } catch(ignored: Exception) { }

        return null
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy