Permalink
Browse files

Upgraded support for Scala 2.12 cross-building.

Migrated away from MetaRx to Reactify.
Updated resource loading to return 404 when trying to list directories instead of throwing exception.
Added forced reload upon WebSocket connection close.
Updated dependencies.
  • Loading branch information...
darkfrog26 committed Jan 17, 2017
1 parent c7db077 commit e73114cb520f4ad650e94f8b0abc6c2bf81d7e13
Showing with 61 additions and 66 deletions.
  1. +1 −1 base/src/main/scala/org/hyperscala/BaseApplication.scala
  2. +1 −1 base/src/main/scala/org/hyperscala/BaseMacros.scala
  3. +1 −1 base/src/main/scala/org/hyperscala/BaseScreen.scala
  4. +1 −1 base/src/main/scala/org/hyperscala/Pickler.scala
  5. +4 −4 core/js/src/main/scala/org/hyperscala/ClientScreen.scala
  6. +4 −2 core/js/src/main/scala/org/hyperscala/ajax/AjaxAction.scala
  7. +0 −1 core/js/src/main/scala/org/hyperscala/ajax/AjaxManager.scala
  8. +1 −1 core/js/src/main/scala/org/hyperscala/ajax/AjaxRequest.scala
  9. +3 −3 core/js/src/main/scala/org/hyperscala/manager/ClientApplicationManager.scala
  10. +5 −7 core/jvm/src/main/scala/org/hyperscala/FunctionalResourceManager.scala
  11. +14 −14 core/jvm/src/main/scala/org/hyperscala/Server.scala
  12. +1 −1 core/jvm/src/main/scala/org/hyperscala/communication/Communication.scala
  13. +3 −3 core/jvm/src/main/scala/org/hyperscala/communication/client/CommunicationClient.scala
  14. +1 −1 core/jvm/src/main/scala/org/hyperscala/communication/server/CommunicationServer.scala
  15. +4 −3 core/jvm/src/main/scala/org/hyperscala/stream/HTMLParser.scala
  16. +3 −3 core/src/main/scala/org/hyperscala/Connection.scala
  17. +1 −4 core/src/main/scala/org/hyperscala/WebApplication.scala
  18. +0 −1 example/jvm/src/main/scala/example/ExampleServer.scala
  19. +2 −2 example/jvm/src/main/scala/example/ExampleSession.scala
  20. +1 −1 example/src/main/scala/example/ExampleApplication.scala
  21. +9 −10 project/HyperscalaBuild.scala
  22. +1 −1 project/plugins.sbt
@@ -1,6 +1,6 @@
package org.hyperscala
import pl.metastack.metarx.Channel
import com.outr.reactify.Channel
import scala.language.experimental.macros
@@ -1,6 +1,6 @@
package org.hyperscala
import pl.metastack.metarx.Channel
import com.outr.reactify.Channel
import scala.annotation.compileTimeOnly
import scala.reflect.macros.blackbox
@@ -1,6 +1,6 @@
package org.hyperscala
import pl.metastack.metarx.Channel
import com.outr.reactify.Channel
import scala.language.experimental.macros
@@ -1,6 +1,6 @@
package org.hyperscala
import pl.metastack.metarx.Channel
import com.outr.reactify.Channel
abstract class Pickler[T](app: Picklers) {
private val receiving = new ThreadLocal[Option[T]] {
@@ -1,17 +1,17 @@
package org.hyperscala
import com.outr.reactify.{Channel, Var}
import org.hyperscala.manager.ClientConnection
import org.scalajs.dom._
import pl.metastack.metarx.{Channel, Sub}
trait ClientScreen extends Screen {
private[hyperscala] var _loaded = false
def loaded: Boolean = _loaded
protected[hyperscala] var activated = false
val title: Sub[Option[String]] = Sub(None)
val stateChange: Channel[StateChange] = Channel()
val title: Var[Option[String]] = Var(None)
val stateChange: Channel[StateChange] = Channel[StateChange]
def urlChanged(url: URL): Unit = {}
@@ -62,7 +62,7 @@ trait ClientScreen extends Screen {
case false => InitState.ScreenLoad
}
_loaded = true
title.attach {
title.attachAndFire {
case Some(t) => if (app.connection.screen.get == this) {
document.title = t
}
@@ -1,11 +1,13 @@
package org.hyperscala.ajax
import pl.metastack.metarx.{StateChannel, Var}
import com.outr.reactify.{StateChannel, Var}
import org.scalajs.dom.XMLHttpRequest
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class AjaxAction(request: AjaxRequest) {
lazy val future = request.promise.future
lazy val future: Future[XMLHttpRequest] = request.promise.future
private[ajax] val _state = Var[ActionState](ActionState.New)
def state: StateChannel[ActionState] = _state
def loaded: StateChannel[Int] = request.loaded
@@ -3,7 +3,6 @@ package org.hyperscala.ajax
import com.outr.scribe.Logging
import org.scalajs.dom.XMLHttpRequest
import org.scalajs.dom.raw.FormData
import pl.metastack.metarx.{StateChannel, Var}
import scala.collection.immutable.Queue
import scala.concurrent.Future
@@ -1,9 +1,9 @@
package org.hyperscala.ajax
import com.outr.reactify.{StateChannel, Var}
import org.scalajs.dom
import org.scalajs.dom._
import org.scalajs.dom.ext.AjaxException
import pl.metastack.metarx.{StateChannel, Var}
import scala.concurrent.{Future, Promise}
@@ -50,7 +50,7 @@ class ClientConnection(val app: WebApplication, val initialURL: URL) extends Con
webSocket.onclose = (evt: CloseEvent) => {
logger.info(s"WebSocket connection closed")
window.setTimeout(() => {
window.location.reload()
window.location.reload(flag = true)
}, 5000)
}
webSocket.onmessage = (evt: MessageEvent) => {
@@ -98,7 +98,7 @@ class ClientConnection(val app: WebApplication, val initialURL: URL) extends Con
})
// Listen for screen changes
screen.attach(screenChanged)
screen.attachAndFire(screenChanged)
}
def pushURL(url: URL, force: Boolean = false): Unit = if (document.location.href != url.toString || force) app.siteType match {
@@ -139,7 +139,7 @@ class ClientConnection(val app: WebApplication, val initialURL: URL) extends Con
}
private def screenChanged(newScreen: BaseScreen): Unit = {
logger.debug(s"screenChanged: $newScreen from $previous")
logger.info(s"screenChanged: $newScreen from $previous")
if (!previous.contains(newScreen)) {
previous match {
case Some(scrn) => scrn match {
@@ -13,7 +13,7 @@ import io.undertow.server.{HttpHandler, HttpServerExchange}
import io.undertow.util.{ByteRange, CanonicalPathUtils, DateUtils, ETagUtils, Headers, Methods, StatusCodes}
import org.xnio.{FileChangeCallback, FileChangeEvent, OptionMap, Xnio}
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
class FunctionalResourceManager(val server: Server) extends ResourceManager {
private var listeners = Set.empty[ResourceChangeListener]
@@ -159,14 +159,14 @@ trait PathResourceMapping extends ResourceMapping {
fileSystemWatcher.watchPath(new File(base), new FileChangeCallback {
override def handleChanges(changes: java.util.Collection[FileChangeEvent]): Unit = resourceManager.synchronized {
val events = changes.collect {
val events = changes.asScala.collect {
case change if change.getFile.getAbsolutePath.startsWith(base) => {
val path = change.getFile.getAbsolutePath.substring(base.length)
new ResourceChangeEvent(path, ResourceChangeEvent.Type.valueOf(change.getType.name()))
}
}
}.toList
if (events.nonEmpty) {
resourceManager.fire(events)
resourceManager.fire(events.asJava)
}
}
})
@@ -222,9 +222,7 @@ class FunctionalResourceHandler(resourceManager: FunctionalResourceManager) exte
resourceResultOption match {
case Some(resourceResult) => {
val resource = resourceResult.resource
if (resource.isDirectory) {
throw new RuntimeException(s"Directories not currently supported: ${exchange.getRelativePath}")
} else if (exchange.getRelativePath.endsWith("/")) {
if (resource.isDirectory || exchange.getRelativePath.endsWith("/")) {
exchange.setStatusCode(StatusCodes.NOT_FOUND)
exchange.endExchange()
} else {
@@ -2,41 +2,41 @@ package org.hyperscala
import java.io.File
import com.outr.reactify.Var
import com.outr.scribe.Logging
import io.undertow.server.session.{SessionAttachmentHandler, SessionConfig, SessionCookieConfig, Session => UndertowSession}
import io.undertow.server.{HttpHandler, HttpServerExchange}
import io.undertow.util.{Headers, Sessions, StatusCodes}
import io.undertow.websockets.WebSocketConnectionCallback
import io.undertow.{Handlers, Undertow}
import org.hyperscala.util.SSLUtil
import pl.metastack.metarx.Sub
import scala.concurrent.duration._
import scala.language.experimental.macros
import scala.language.implicitConversions
class Server extends Logging with HttpHandler {
object config {
val autoRestart: Sub[Boolean] = sub(true)
val host: Sub[String] = sub("0.0.0.0")
val port: Sub[Int] = sub(8080)
val autoRestart: Var[Boolean] = sub(true)
val host: Var[String] = sub("0.0.0.0")
val port: Var[Int] = sub(8080)
object https {
val enabled: Sub[Boolean] = sub(false)
val host: Sub[String] = sub("0.0.0.0")
val port: Sub[Int] = sub(8443)
val password: Sub[String] = sub("password")
val keyStoreLocation: Sub[File] = sub(new File("keystore.jks"))
val enabled: Var[Boolean] = sub(false)
val host: Var[String] = sub("0.0.0.0")
val port: Var[Int] = sub(8443)
val password: Var[String] = sub("password")
val keyStoreLocation: Var[File] = sub(new File("keystore.jks"))
}
object session {
val domain: Sub[Option[String]] = sub(None)
val maxAge: Sub[FiniteDuration] = sub(0.seconds)
val domain: Var[Option[String]] = sub(None)
val maxAge: Var[FiniteDuration] = sub(0.seconds)
}
private def sub[T](value: T): Sub[T] = {
val s = Sub[T](value)
s.silentAttach { value =>
private def sub[T](value: T): Var[T] = {
val s = Var[T](value)
s.attach { value =>
if (autoRestart.get && isStarted) {
restart()
}
@@ -1,7 +1,7 @@
package org.hyperscala.communication
import com.outr.reactify.Channel
import org.hyperscala.{BaseMacros, Pickler, Picklers}
import pl.metastack.metarx.Channel
import scala.language.experimental.macros
@@ -4,6 +4,7 @@ import java.io.File
import java.net.URI
import java.util
import com.outr.reactify.{Channel, Var}
import io.undertow.protocols.ssl.UndertowXnioSsl
import io.undertow.server.DefaultByteBufferPool
import io.undertow.util.Headers
@@ -13,9 +14,8 @@ import io.undertow.websockets.core.{AbstractReceiveListener, BufferedTextMessage
import org.hyperscala.communication.Communication
import org.hyperscala.util.SSLUtil
import org.xnio.{OptionMap, Options, Xnio}
import pl.metastack.metarx.{Channel, Var}
import scala.collection.JavaConversions._
import scala.collection.JavaConverters._
class CommunicationClient(uri: URI,
keyStoreFile: Option[File] = None,
@@ -47,7 +47,7 @@ class CommunicationClient(uri: URI,
.setClientNegotiation(new WebSocketClientNegotiation(null, null) {
override def beforeRequest(headers: util.Map[String, util.List[String]]): Unit = {
authorization.foreach { auth =>
headers.put(Headers.AUTHORIZATION_STRING, List(auth))
headers.put(Headers.AUTHORIZATION_STRING, List(auth).asJava)
}
}
})
@@ -1,13 +1,13 @@
package org.hyperscala.communication.server
import com.outr.reactify.Channel
import io.undertow.Handlers
import io.undertow.util.Headers
import io.undertow.websockets.WebSocketConnectionCallback
import io.undertow.websockets.core.{AbstractReceiveListener, BufferedTextMessage, StreamSourceFrameChannel, WebSocketChannel, WebSockets}
import io.undertow.websockets.spi.WebSocketHttpExchange
import org.hyperscala.communication.Communication
import org.hyperscala.{Handler, Server}
import pl.metastack.metarx.Channel
class CommunicationServer(path: String,
authorization: WebSocketHttpExchange => Option[String] = (exchange: WebSocketHttpExchange) => None
@@ -139,7 +139,7 @@ class HTMLParser(input: InputStream) {
private var tagStart = -1
private var tagEnd = -1
private val open = new mutable.Stack[OpenTag]
private var open = List.empty[OpenTag]
private var tags = Set.empty[OpenTag]
@tailrec
@@ -191,7 +191,7 @@ class HTMLParser(input: InputStream) {
case OpenTagRegex(tagName, attributes) => {
val a = parseAttributes(attributes)
val tag = OpenTag(tagName, a, tagStart, tagEnd, close = None)
open.push(tag)
open = tag :: open
}
}
@@ -232,7 +232,8 @@ class HTMLParser(input: InputStream) {
if (open.isEmpty) {
throw new RuntimeException(s"Missing close tag for $tagName!")
}
val t = open.pop()
val t = open.head
open = open.tail
if (t.tagName.equalsIgnoreCase(tagName)) {
t
} else {
@@ -1,16 +1,16 @@
package org.hyperscala
import com.outr.reactify.Var
import com.outr.scribe.Logging
import pl.metastack.metarx.Sub
trait Connection extends Logging {
protected[hyperscala] var replace = false
def app: WebApplication
def initialURL: URL
lazy val url: Sub[URL] = Sub(initialURL)
lazy val screen: Sub[BaseScreen] = Sub(app.byURL(initialURL))
lazy val url: Var[URL] = Var[URL](initialURL)
lazy val screen: Var[BaseScreen] = Var[BaseScreen](app.byURL(initialURL))
def init(): Unit = {
logger.info(s"Initial URL: ${url.get}, Starting Screen: ${screen.get}")
@@ -1,16 +1,13 @@
package org.hyperscala
import com.outr.reactify.Channel
import com.outr.scribe.Logging
import org.hyperscala.manager.ApplicationManager
import pl.metastack.metarx.Channel
import org.hyperscala.manager._
import scala.language.experimental.macros
abstract class WebApplication(val siteType: SiteType) extends BaseApplication with Logging {
Channel.ValidateCyclical = false
protected[hyperscala] var picklers = Vector.empty[Pickler[_]]
private var _screens = Vector.empty[Screen]
private[hyperscala] var screensByName = Map.empty[String, Screen]
@@ -8,7 +8,6 @@ object ExampleServer {
val server = Server(ExampleApplication)
server.config.host := "0.0.0.0"
server.config.port := 8080
server.config.session.domain := Some(".asuscomm.com")
def session: ExampleSession = ExampleSession()
@@ -1,10 +1,10 @@
package example
import com.outr.reactify.Var
import org.hyperscala.{DefaultSessionManager, Session}
import pl.metastack.metarx.Sub
class ExampleSession extends Session {
val username: Sub[Option[String]] = Sub[Option[String]](None)
val username: Var[Option[String]] = Var[Option[String]](None)
}
object ExampleSession extends DefaultSessionManager[ExampleSession] {
@@ -1,7 +1,7 @@
package example
import com.outr.reactify.Channel
import org.hyperscala.{Screen, SimpleScreen, SiteType, URL, WebApplication}
import pl.metastack.metarx.Channel
object ExampleApplication extends WebApplication(SiteType.SinglePage) {
val login = create[LoginScreen]
Oops, something went wrong.

0 comments on commit e73114c

Please sign in to comment.