Network.kt

  1. package com.hexagontk.core

  2. import java.io.File
  3. import java.net.*
  4. import java.util.*

  5. /** Internet address used to bind services to all local network interfaces. */
  6. val ALL_INTERFACES: InetAddress by lazy { inetAddress(0, 0, 0, 0) }

  7. /** Internet address used to bind services to the loop-back interface. */
  8. val LOOPBACK_INTERFACE: InetAddress by lazy { inetAddress(127, 0, 0, 1) }

  9. /**
  10.  * Syntactic sugar to create an Internet address.
  11.  *
  12.  * @param bytes Bytes used in the address.
  13.  * @return The Internet address corresponding with the supplied bytes.
  14.  */
  15. fun inetAddress(vararg bytes: Byte): InetAddress =
  16.     InetAddress.getByAddress(bytes)

  17. /**
  18.  * Return a random free port (not used by any other local process).
  19.  *
  20.  * @return Random free port number.
  21.  */
  22. fun freePort(): Int =
  23.     ServerSocket(0).use { it.localPort }

  24. /**
  25.  * Check if a port is already opened.
  26.  *
  27.  * @param port Port number to check.
  28.  * @return True if the port is open, false otherwise.
  29.  */
  30. fun isPortOpened(port: Int): Boolean =
  31.     try {
  32.         Socket("localhost", port).use { it.isConnected }
  33.     }
  34.     catch (_: Exception) {
  35.         false
  36.     }

  37. fun urlOf(url: String): URL =
  38.     URI(url).toURL()

  39. fun URL.responseCode(): Int =
  40.     try {
  41.         (openConnection() as HttpURLConnection).responseCode
  42.     }
  43.     catch (_: java.lang.Exception) {
  44.         400
  45.     }

  46. fun URL.responseSuccessful(): Boolean =
  47.     responseCode() in 200 until 300

  48. fun URL.responseFound(): Boolean =
  49.     responseCode().let { it in 200 until 500 && it != 404 }

  50. // TODO Review the next functions, not all cases are covered
  51. fun URL.exists(): Boolean =
  52.     when (protocol) {
  53.         "http" -> responseSuccessful()
  54.         "https" -> responseSuccessful()
  55.         "file" -> File(file).let { it.exists() && !it.isDirectory }
  56.         "classpath" -> try { openConnection(); true } catch (_: Exception) { false }
  57.         else -> false
  58.     }

  59. fun URL.firstVariant(vararg suffixes: String): URL {
  60.     val extension = file.substringAfter('.')
  61.     val fileName = file.removeSuffix(".$extension")

  62.     suffixes.forEach {
  63.         val u = urlOf("$protocol:$fileName$it.$extension")
  64.         if (u.exists())
  65.             return u
  66.     }

  67.     return this
  68. }

  69. fun URL.localized(locale: Locale): URL {
  70.     val language = locale.language
  71.     val country = locale.country
  72.     return firstVariant("_${language}_$country", "_${language}")
  73. }