|
Akka/Scala example source code file (Address.scala)
The Address.scala Akka example source code/** * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package akka.actor import java.net.URI import java.net.URISyntaxException import java.net.MalformedURLException import scala.annotation.tailrec import scala.collection.immutable /** * The address specifies the physical location under which an Actor can be * reached. Examples are local addresses, identified by the ActorSystem’s * name, and remote addresses, identified by protocol, host and port. * * This class is final to allow use as a case class (copy method etc.); if * for example a remote transport would want to associate additional * information with an address, then this must be done externally. */ @SerialVersionUID(1L) final case class Address private (protocol: String, system: String, host: Option[String], port: Option[Int]) { // Please note that local/non-local distinction must be preserved: // host.isDefined == hasGlobalScope // host.isEmpty == hasLocalScope // hasLocalScope == !hasGlobalScope def this(protocol: String, system: String) = this(protocol, system, None, None) def this(protocol: String, system: String, host: String, port: Int) = this(protocol, system, Option(host), Some(port)) /** * Returns true if this Address is only defined locally. It is not safe to send locally scoped addresses to remote * hosts. See also [[akka.actor.Address#hasGlobalScope]]. */ def hasLocalScope: Boolean = host.isEmpty /** * Returns true if this Address is usable globally. Unlike locally defined addresses ([[akka.actor.Address#hasLocalScope]]) * addresses of global scope are safe to sent to other hosts, as they globally and uniquely identify an addressable * entity. */ def hasGlobalScope: Boolean = host.isDefined // store hashCode @transient override lazy val hashCode: Int = scala.util.hashing.MurmurHash3.productHash(this) /** * Returns the canonical String representation of this Address formatted as: * * <protocol>://<system>@<host>:<port> */ @transient override lazy val toString: String = { val sb = (new java.lang.StringBuilder(protocol)).append("://").append(system) if (host.isDefined) sb.append('@').append(host.get) if (port.isDefined) sb.append(':').append(port.get) sb.toString } /** * Returns a String representation formatted as: * * <system>@<host>:<port> */ def hostPort: String = toString.substring(protocol.length + 3) } object Address { /** * Constructs a new Address with the specified protocol and system name */ def apply(protocol: String, system: String) = new Address(protocol, system) /** * Constructs a new Address with the specified protocol, system name, host and port */ def apply(protocol: String, system: String, host: String, port: Int) = new Address(protocol, system, Some(host), Some(port)) } private[akka] trait PathUtils { protected def split(s: String, fragment: String): List[String] = { @tailrec def rec(pos: Int, acc: List[String]): List[String] = { val from = s.lastIndexOf('/', pos - 1) val sub = s.substring(from + 1, pos) val l = if ((fragment ne null) && acc.isEmpty) sub + "#" + fragment :: acc else sub :: acc if (from == -1) l else rec(from, l) } rec(s.length, Nil) } } /** * Extractor for so-called “relative actor paths” as in “relative URI”, not in * “relative to some actor”. Examples: * * * "grand/child" * * "/user/hello/world" */ object RelativeActorPath extends PathUtils { def unapply(addr: String): Option[immutable.Seq[String]] = { try { val uri = new URI(addr) if (uri.isAbsolute) None else Some(split(uri.getRawPath, uri.getRawFragment)) } catch { case _: URISyntaxException ⇒ None } } } /** * This object serves as extractor for Scala and as address parser for Java. */ object AddressFromURIString { def unapply(addr: String): Option[Address] = try unapply(new URI(addr)) catch { case _: URISyntaxException ⇒ None } def unapply(uri: URI): Option[Address] = if (uri eq null) None else if (uri.getScheme == null || (uri.getUserInfo == null && uri.getHost == null)) None else if (uri.getUserInfo == null) { // case 1: “akka://system” if (uri.getPort != -1) None else Some(Address(uri.getScheme, uri.getHost)) } else { // case 2: “akka://system@host:port” if (uri.getHost == null || uri.getPort == -1) None else Some( if (uri.getUserInfo == null) Address(uri.getScheme, uri.getHost) else Address(uri.getScheme, uri.getUserInfo, uri.getHost, uri.getPort)) } /** * Try to construct an Address from the given String or throw a java.net.MalformedURLException. */ def apply(addr: String): Address = addr match { case AddressFromURIString(address) ⇒ address case _ ⇒ throw new MalformedURLException(addr) } /** * Java API: Try to construct an Address from the given String or throw a java.net.MalformedURLException. */ def parse(addr: String): Address = apply(addr) } /** * Given an ActorPath it returns the Address and the path elements if the path is well-formed */ object ActorPathExtractor extends PathUtils { def unapply(addr: String): Option[(Address, immutable.Iterable[String])] = try { val uri = new URI(addr) uri.getRawPath match { case null ⇒ None case path ⇒ AddressFromURIString.unapply(uri).map((_, split(path, uri.getRawFragment).drop(1))) } } catch { case _: URISyntaxException ⇒ None } } Other Akka source code examplesHere is a short list of links related to this Akka Address.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.