add Java API for most case objects

- “case object” will emit a concrete class without constructor, so put
  abstract class in its way in order to obtain an accessible type for
  Scala & Java (i.e. without $)
- add “def instance = this” to make access uniform from Java
- this does not work for nested case objects because of missing static
  forwarders, so keep those as they were
- fix issue with case object FromConfig colliding with case class
  FromConfig by open-coding the “case”iness in this case (should be
  thrown out in 2.1)
This commit is contained in:
Roland 2012-04-10 12:07:14 +02:00
parent 21f2c28fd1
commit b6db48818a
6 changed files with 99 additions and 18 deletions

View file

@ -1,7 +1,12 @@
package akka.actor; package akka.actor;
import akka.actor.ActorSystem; import akka.actor.ActorSystem;
import akka.event.Logging;
import akka.event.Logging.LoggerInitialized;
import akka.japi.Creator; import akka.japi.Creator;
import akka.routing.CurrentRoutees;
import akka.routing.FromConfig;
import akka.routing.NoRouter;
import akka.testkit.AkkaSpec; import akka.testkit.AkkaSpec;
import org.junit.AfterClass; import org.junit.AfterClass;
@ -24,6 +29,23 @@ public class JavaAPI {
system = null; system = null;
} }
// compilation tests
@SuppressWarnings("unused")
public void mustCompile() {
final Kill kill = Kill.instance();
final PoisonPill pill = PoisonPill.instance();
final ReceiveTimeout t = ReceiveTimeout.instance();
final LocalScope ls = LocalScope.instance();
final NoScopeGiven noscope = NoScopeGiven.instance();
final LoggerInitialized x = Logging.loggerInitialized();
final CurrentRoutees r = CurrentRoutees.instance();
final NoRouter nr = NoRouter.instance();
final FromConfig fc = FromConfig.instance();
}
@Test @Test
public void mustBeAbleToCreateActorRefFromClass() { public void mustBeAbleToCreateActorRefFromClass() {
ActorRef ref = system.actorOf(new Props(JavaAPITestActor.class)); ActorRef ref = system.actorOf(new Props(JavaAPITestActor.class));

View file

@ -28,13 +28,22 @@ trait NoSerializationVerificationNeeded
case class Failed(cause: Throwable) extends AutoReceivedMessage with PossiblyHarmful case class Failed(cause: Throwable) extends AutoReceivedMessage with PossiblyHarmful
case object PoisonPill extends AutoReceivedMessage with PossiblyHarmful abstract class PoisonPill extends AutoReceivedMessage with PossiblyHarmful
case object PoisonPill extends PoisonPill {
def instance = this
}
case object Kill extends AutoReceivedMessage with PossiblyHarmful abstract class Kill extends AutoReceivedMessage with PossiblyHarmful
case object Kill extends Kill {
def instance = this
}
case class Terminated(@BeanProperty actor: ActorRef) extends PossiblyHarmful case class Terminated(@BeanProperty actor: ActorRef) extends PossiblyHarmful
case object ReceiveTimeout extends PossiblyHarmful abstract class ReceiveTimeout extends PossiblyHarmful
case object ReceiveTimeout extends ReceiveTimeout {
def instance = this
}
/** /**
* ActorRefFactory.actorSelection returns a special ref which sends these * ActorRefFactory.actorSelection returns a special ref which sends these

View file

@ -63,12 +63,16 @@ trait Scope {
} }
//TODO add @SerialVersionUID(1L) when SI-4804 is fixed //TODO add @SerialVersionUID(1L) when SI-4804 is fixed
case object LocalScope extends Scope { abstract class LocalScope extends Scope
case object LocalScope extends LocalScope {
/** /**
* Java API * Java API
*/ */
@deprecated("use instance() method instead", "2.0.1")
def scope: Scope = this def scope: Scope = this
def instance = this
def withFallback(other: Scope): Scope = this def withFallback(other: Scope): Scope = this
} }
@ -76,8 +80,11 @@ case object LocalScope extends Scope {
* This is the default value and as such allows overrides. * This is the default value and as such allows overrides.
*/ */
//TODO add @SerialVersionUID(1L) when SI-4804 is fixed //TODO add @SerialVersionUID(1L) when SI-4804 is fixed
case object NoScopeGiven extends Scope { abstract class NoScopeGiven extends Scope
case object NoScopeGiven extends NoScopeGiven {
def withFallback(other: Scope): Scope = other def withFallback(other: Scope): Scope = other
def instance = this
} }
/** /**

View file

@ -588,12 +588,16 @@ object Logging {
* InitializeLogger request. If initialization takes longer, send the reply * InitializeLogger request. If initialization takes longer, send the reply
* as soon as subscriptions are set-up. * as soon as subscriptions are set-up.
*/ */
case object LoggerInitialized abstract class LoggerInitialized
case object LoggerInitialized extends LoggerInitialized {
def instance = this
}
/** /**
* Java API to create a LoggerInitialized message. * Java API to create a LoggerInitialized message.
*/ */
def loggerInitialized() = LoggerInitialized // weird return type due to binary compatibility
def loggerInitialized(): LoggerInitialized.type = LoggerInitialized
class LoggerInitializationException(msg: String) extends AkkaException(msg) class LoggerInitializationException(msg: String) extends AkkaException(msg)

View file

@ -17,7 +17,8 @@ import java.util.concurrent.locks.ReentrantLock
import akka.jsr166y.ThreadLocalRandom import akka.jsr166y.ThreadLocalRandom
import akka.util.Unsafe import akka.util.Unsafe
import akka.dispatch.Dispatchers import akka.dispatch.Dispatchers
import annotation.tailrec import scala.annotation.tailrec
import scala.runtime.ScalaRunTime
/** /**
* A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to * A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to
@ -343,7 +344,10 @@ case class Broadcast(message: Any)
* A RouterRoutees message is sent asynchronously to the "requester" containing information * A RouterRoutees message is sent asynchronously to the "requester" containing information
* about what routees the router is routing over. * about what routees the router is routing over.
*/ */
case object CurrentRoutees abstract class CurrentRoutees
case object CurrentRoutees extends CurrentRoutees {
def instance = this
}
/** /**
* Message used to carry information about what routees the router is currently using. * Message used to carry information about what routees the router is currently using.
@ -365,21 +369,23 @@ case class Destination(sender: ActorRef, recipient: ActorRef)
* router is taken in the LocalActorRefProvider based on Props. * router is taken in the LocalActorRefProvider based on Props.
*/ */
//TODO add @SerialVersionUID(1L) when SI-4804 is fixed //TODO add @SerialVersionUID(1L) when SI-4804 is fixed
case object NoRouter extends RouterConfig { abstract class NoRouter extends RouterConfig
case object NoRouter extends NoRouter {
def createRoute(props: Props, routeeProvider: RouteeProvider): Route = null def createRoute(props: Props, routeeProvider: RouteeProvider): Route = null
def routerDispatcher: String = "" def routerDispatcher: String = ""
def supervisorStrategy = null def supervisorStrategy = null
override def withFallback(other: RouterConfig): RouterConfig = other override def withFallback(other: RouterConfig): RouterConfig = other
def instance = this
} }
/** /**
* Router configuration which has no default, i.e. external configuration is required. * Router configuration which has no default, i.e. external configuration is required.
*/ */
case object FromConfig extends RouterConfig { case object FromConfig extends FromConfig {
def createRoute(props: Props, routeeProvider: RouteeProvider): Route = def instance = this
throw new ConfigurationException("router " + routeeProvider.context.self + " needs external configuration from file (e.g. application.conf)") def apply(routerDispatcher: String = Dispatchers.DefaultDispatcherId) = new FromConfig(routerDispatcher)
def routerDispatcher: String = Dispatchers.DefaultDispatcherId def unapply(fc: FromConfig): Option[String] = Some(fc.routerDispatcher)
def supervisorStrategy: SupervisorStrategy = Router.defaultSupervisorStrategy
} }
/** /**
@ -389,7 +395,11 @@ case object FromConfig extends RouterConfig {
* (defaults to default-dispatcher). * (defaults to default-dispatcher).
*/ */
//TODO add @SerialVersionUID(1L) when SI-4804 is fixed //TODO add @SerialVersionUID(1L) when SI-4804 is fixed
case class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatcherId) extends RouterConfig { class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatcherId)
extends RouterConfig
with Product
with Serializable
with Equals {
def this() = this(Dispatchers.DefaultDispatcherId) def this() = this(Dispatchers.DefaultDispatcherId)
@ -397,6 +407,31 @@ case class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatch
throw new ConfigurationException("router " + routeeProvider.context.self + " needs external configuration from file (e.g. application.conf)") throw new ConfigurationException("router " + routeeProvider.context.self + " needs external configuration from file (e.g. application.conf)")
def supervisorStrategy: SupervisorStrategy = Router.defaultSupervisorStrategy def supervisorStrategy: SupervisorStrategy = Router.defaultSupervisorStrategy
// open-coded case class to preserve binary compatibility, all deprecated for 2.1
@deprecated("FromConfig does not make sense as case class", "2.0.1")
override def productPrefix = "FromConfig"
@deprecated("FromConfig does not make sense as case class", "2.0.1")
def productArity = 1
@deprecated("FromConfig does not make sense as case class", "2.0.1")
def productElement(x: Int) = x match {
case 0 routerDispatcher
case _ throw new IndexOutOfBoundsException(x.toString)
}
@deprecated("FromConfig does not make sense as case class", "2.0.1")
def copy(d: String = Dispatchers.DefaultDispatcherId): FromConfig = new FromConfig(d)
@deprecated("FromConfig does not make sense as case class", "2.0.1")
def canEqual(o: Any) = o.isInstanceOf[FromConfig]
@deprecated("FromConfig does not make sense as case class", "2.0.1")
override def hashCode = ScalaRunTime._hashCode(this)
@deprecated("FromConfig does not make sense as case class", "2.0.1")
override def toString = "FromConfig(" + routerDispatcher + ")"
@deprecated("FromConfig does not make sense as case class", "2.0.1")
override def equals(other: Any): Boolean = other match {
case FromConfig(x) x == routerDispatcher
case _ false
}
} }
object RoundRobinRouter { object RoundRobinRouter {

View file

@ -11,8 +11,12 @@ sealed trait Response
/** /**
* When the ZeroMQ socket connects it sends this message to a listener * When the ZeroMQ socket connects it sends this message to a listener
*/ */
case object Connecting extends Response case object Connecting extends Response {
def instance = this
}
/** /**
* When the ZeroMQ socket disconnects it sends this message to a listener * When the ZeroMQ socket disconnects it sends this message to a listener
*/ */
case object Closed extends Response case object Closed extends Response {
def instance = this
}