Skip to content

Instantly share code, notes, and snippets.

@aappddeevv
Created December 24, 2013 11:41
Show Gist options
  • Save aappddeevv/8112110 to your computer and use it in GitHub Desktop.
Save aappddeevv/8112110 to your computer and use it in GitHub Desktop.

This is a URL handler I needed for my javafx application in order to allow WebView (WebEngine) find my classpath resources and use relative resources for images, scripts, etc. If you only use WebEngine.loadContent, you cannot use relative resources and your web pages become much less flexible when changing later.

/**
 * Handler factory different types of URL handling.
 */
class ConfigurableStreamHandlerFactory extends URLStreamHandlerFactory {

  private var handlers = Map[String, URLStreamHandler]()

  /**
   * Add an instance as a handler.
   */
  def addHandler(protocol: String, handler: URLStreamHandler): Unit = {
    handlers = handlers + (protocol -> handler)
  }

  /**
   * Add a closure as a handler.
   */
  def addHandler(protocol: String, handler: URL => URLConnection): Unit = {
    addHandler(protocol, new URLStreamHandler() {
      def openConnection(url: URL): URLConnection = {
        handler(url)
      }
    })
  }

  override def createURLStreamHandler(protocol: String): URLStreamHandler =
    handlers.get(protocol).getOrElse(null)

}

/**
 * This can only be set once in an application. To use this factory in your
 * application you must initialize like below:
 * {{{
 * URL.setHandlerFactory(ConfigurableStreamHandlerFactory)
 * }}}
 * The application should register handlers using this singleton object.
 */
object ConfigurableStreamHandlerFactory extends ConfigurableStreamHandlerFactory

/**
 * Bucket of functions to create some URL handlers.
 */
object URLProtocolHandlers {
  /**
   * Create a URL protocol handler based on a classloader. Make sure
   * you watch your class loader and thread use!
   */
  def handlerForClasspath(classLoader: ClassLoader = Thread.currentThread().getContextClassLoader()) =
    (url: URL) => {
      val path = url.getPath
      classLoader.getResource(if (path.length ==0)
        ""
      else if(path(0) == '/')
        path.drop(1)
      else
        path) match {
        case x: URL => x.openConnection()
        case _ =>
          null
      }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment