diff --git a/akka-actor/src/main/scala/actor/Agent.scala b/akka-actor/src/main/scala/actor/Agent.scala index e5b00d4f5e..76e3e1d9db 100644 --- a/akka-actor/src/main/scala/actor/Agent.scala +++ b/akka-actor/src/main/scala/actor/Agent.scala @@ -6,7 +6,7 @@ package se.scalablesolutions.akka.actor import se.scalablesolutions.akka.stm.Ref import se.scalablesolutions.akka.AkkaException -import se.scalablesolutions.akka.util.{ Function => JFunc, Procedure => JProc } +import se.scalablesolutions.akka.util.JavaAPI.{ Function => JFunc, Procedure => JProc } import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.CountDownLatch diff --git a/akka-actor/src/main/scala/dataflow/DataFlowVariable.scala b/akka-actor/src/main/scala/dataflow/DataFlowVariable.scala index 329682de52..9c91b40833 100644 --- a/akka-actor/src/main/scala/dataflow/DataFlowVariable.scala +++ b/akka-actor/src/main/scala/dataflow/DataFlowVariable.scala @@ -11,7 +11,7 @@ import se.scalablesolutions.akka.actor.{Actor, ActorRef} import se.scalablesolutions.akka.actor.Actor._ import se.scalablesolutions.akka.dispatch.CompletableFuture import se.scalablesolutions.akka.AkkaException -import se.scalablesolutions.akka.util.{ Function, SideEffect } +import se.scalablesolutions.akka.util.JavaAPI.{ Function, SideEffect } /** * Implements Oz-style dataflow (single assignment) variables. diff --git a/akka-actor/src/main/scala/util/JavaAPI.scala b/akka-actor/src/main/scala/util/JavaAPI.scala index 099082595d..0fa7abd738 100644 --- a/akka-actor/src/main/scala/util/JavaAPI.scala +++ b/akka-actor/src/main/scala/util/JavaAPI.scala @@ -1,23 +1,70 @@ package se.scalablesolutions.akka.util -/** A Function interface - * Used to create first-class-functions is Java (sort of) - * Java API - */ -trait Function[T,R] { - def apply(param: T): R +object JavaAPI { + /** A Function interface + * Used to create first-class-functions is Java (sort of) + * Java API + */ + trait Function[T,R] { + def apply(param: T): R + } + + /** A Procedure is like a Function, but it doesn't produce a return value + * Java API + */ + trait Procedure[T] { + def apply(param: T): Unit + } + + /** + * An executable piece of code that takes no parameters and doesn't return any value + */ + trait SideEffect { + def apply: Unit + } + + /** + * This class represents optional values. Instances of Option + * are either instances of case class Some or it is case + * object None. + *

+ * Java API + */ + sealed abstract class Option[A] extends java.lang.Iterable[A] { + def get: A + def isDefined: Boolean + } + + /** + * Class Some[A] represents existing values of type + * A. + *

+ * Java API + */ + final case class Some[A](v: A) extends Option[A] { + import scala.collection.JavaConversions._ + + val sv = scala.Some(v) + + def get = sv.get + def iterator = sv.iterator + def isDefined = true + } + + /** + * This case object represents non-existent values. + *

+ * Java API + */ + case class None[A]() extends Option[A] { + import scala.collection.JavaConversions._ + + def get = throw new NoSuchElementException("None.get") + def iterator = scala.None.iterator + def isDefined = false + } + + def some[A](v: A) = Some(v) + def none[A] = None[A] } -/** A Procedure is like a Function, but it doesn't produce a return value - * Java API - */ -trait Procedure[T] { - def apply(param: T): Unit -} - -/** - * An executable piece of code that takes no parameters and doesn't return any value - */ -trait SideEffect { - def apply: Unit -} diff --git a/akka-camel/src/main/scala/CamelService.scala b/akka-camel/src/main/scala/CamelService.scala index 22b536e383..3e4097ebcf 100644 --- a/akka-camel/src/main/scala/CamelService.scala +++ b/akka-camel/src/main/scala/CamelService.scala @@ -10,7 +10,8 @@ import org.apache.camel.CamelContext import se.scalablesolutions.akka.actor.Actor._ import se.scalablesolutions.akka.actor.{AspectInitRegistry, ActorRegistry} import se.scalablesolutions.akka.config.Config._ -import se.scalablesolutions.akka.util.{Bootable, Logging} +import se.scalablesolutions.akka.util.{Logging, Bootable} +import se.scalablesolutions.akka.util.JavaAPI.{Option => JOption, Some => JSome, None => JNone} /** * Publishes (untyped) consumer actors and typed consumer actors via Camel endpoints. Actors @@ -73,7 +74,7 @@ trait CamelService extends Bootable with Logging { // Register this instance as current CamelService and return it CamelServiceManager.register(this) - CamelServiceManager.service + CamelServiceManager.service.get } /** @@ -136,16 +137,22 @@ object CamelServiceManager { * @see CamelService#stop * @see CamelService#onUnload */ - def stopCamelService = service.stop + def stopCamelService = for (s <- service) s.stop + + /** + * Returns Some(CamelService) if CamelService + * has been started, None otherwise. + */ + def service = _current /** * Returns the current CamelService. * * @throws IllegalStateException if there's no current CamelService. */ - def service = - if (_current.isDefined) _current.get - else throw new IllegalStateException("no current CamelService") + def getService: JOption[CamelService] = { + if (_current.isDefined) JSome(_current.get) else JNone[CamelService] + } private[camel] def register(service: CamelService) = if (_current.isDefined) throw new IllegalStateException("current CamelService already registered") diff --git a/akka-camel/src/test/scala/CamelServiceManagerTest.scala b/akka-camel/src/test/scala/CamelServiceManagerTest.scala index fd15ce7154..8f7916d574 100644 --- a/akka-camel/src/test/scala/CamelServiceManagerTest.scala +++ b/akka-camel/src/test/scala/CamelServiceManagerTest.scala @@ -10,19 +10,22 @@ import se.scalablesolutions.akka.actor.ActorRegistry */ class CamelServiceManagerTest extends WordSpec with BeforeAndAfterAll with MustMatchers { - override def afterAll = ActorRegistry.shutdownAll + override def afterAll = { + CamelServiceManager.stopCamelService + ActorRegistry.shutdownAll + } "A CamelServiceManager" when { "the startCamelService method been has been called" must { "have registered the started CamelService instance" in { val service = CamelServiceManager.startCamelService - CamelServiceManager.service must be theSameInstanceAs (service) + CamelServiceManager.service.get must be theSameInstanceAs (service) } } "the stopCamelService method been has been called" must { "have unregistered the current CamelService instance" in { val service = CamelServiceManager.stopCamelService - intercept[IllegalStateException] { CamelServiceManager.service } + CamelServiceManager.service must be (None) } } } @@ -32,13 +35,13 @@ class CamelServiceManagerTest extends WordSpec with BeforeAndAfterAll with MustM "a CamelService instance has been started externally" must { "have registered the started CamelService instance" in { service.start - CamelServiceManager.service must be theSameInstanceAs (service) + CamelServiceManager.service.get must be theSameInstanceAs (service) } } "the current CamelService instance has been stopped externally" must { "have unregistered the current CamelService instance" in { service.stop - intercept[IllegalStateException] { CamelServiceManager.service } + CamelServiceManager.service must be (None) } } } @@ -54,10 +57,6 @@ class CamelServiceManagerTest extends WordSpec with BeforeAndAfterAll with MustM "only allow the current CamelService instance to be stopped" in { intercept[IllegalStateException] { CamelServiceFactory.createCamelService.stop } } - "ensure that the current CamelService instance has been actually started" in { - CamelServiceManager.stopCamelService - intercept[IllegalStateException] { CamelServiceManager.stopCamelService } - } } } } diff --git a/akka-camel/src/test/scala/RemoteConsumerTest.scala b/akka-camel/src/test/scala/RemoteConsumerTest.scala index afba2011d5..8d80d05b36 100644 --- a/akka-camel/src/test/scala/RemoteConsumerTest.scala +++ b/akka-camel/src/test/scala/RemoteConsumerTest.scala @@ -45,7 +45,7 @@ class RemoteConsumerTest extends FeatureSpec with BeforeAndAfterAll with GivenWh val consumer = actorOf[RemoteConsumer].start when("remote consumer publication is triggered") - var latch = service.expectEndpointActivationCount(1) + var latch = service.get.expectEndpointActivationCount(1) consumer !! "init" assert(latch.await(5000, TimeUnit.MILLISECONDS)) @@ -61,7 +61,7 @@ class RemoteConsumerTest extends FeatureSpec with BeforeAndAfterAll with GivenWh val consumer = TypedActor.newRemoteInstance(classOf[SampleRemoteTypedConsumer], classOf[SampleRemoteTypedConsumerImpl], host, port) when("remote typed consumer publication is triggered") - var latch = service.expectEndpointActivationCount(1) + var latch = service.get.expectEndpointActivationCount(1) consumer.foo("init") assert(latch.await(5000, TimeUnit.MILLISECONDS)) @@ -77,7 +77,7 @@ class RemoteConsumerTest extends FeatureSpec with BeforeAndAfterAll with GivenWh val consumer = UntypedActor.actorOf(classOf[SampleRemoteUntypedConsumer]).start when("remote untyped consumer publication is triggered") - var latch = service.expectEndpointActivationCount(1) + var latch = service.get.expectEndpointActivationCount(1) consumer.sendRequestReply(Message("init", Map("test" -> "init"))) assert(latch.await(5000, TimeUnit.MILLISECONDS)) diff --git a/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala b/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala index c86295da57..6a8aa461a8 100644 --- a/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala +++ b/akka-samples/akka-sample-camel/src/main/scala/StandaloneApplication.scala @@ -29,7 +29,7 @@ object StandaloneApplication extends Application { assert("hello msg1" == context.createProducerTemplate.requestBody("direct:test", "msg1")) // set expectations on upcoming endpoint activation - val activation = service.expectEndpointActivationCount(1) + val activation = service.get.expectEndpointActivationCount(1) // 'internally' register typed actor (requires CamelService) TypedActor.newInstance(classOf[TypedConsumer2], classOf[TypedConsumer2Impl]) @@ -86,7 +86,7 @@ object StandaloneJmsApplication extends Application { startCamelService // Expect two consumer endpoints to be activated - val completion = service.expectEndpointActivationCount(2) + val completion = service.get.expectEndpointActivationCount(2) val jmsUri = "jms:topic:test" // Wire publisher and consumer using a JMS topic diff --git a/akka-samples/akka-sample-camel/src/test/scala/HttpConcurrencyTestStress.scala b/akka-samples/akka-sample-camel/src/test/scala/HttpConcurrencyTestStress.scala index 3813463601..76cbc58a8b 100644 --- a/akka-samples/akka-sample-camel/src/test/scala/HttpConcurrencyTestStress.scala +++ b/akka-samples/akka-sample-camel/src/test/scala/HttpConcurrencyTestStress.scala @@ -50,7 +50,7 @@ object HttpConcurrencyTestStress { val workers = for (i <- 1 to 8) yield actorOf[HttpServerWorker].start val balancer = loadBalancerActor(new CyclicIterator(workers.toList)) - val completion = service.expectEndpointActivationCount(1) + val completion = service.get.expectEndpointActivationCount(1) val server = actorOf(new HttpServerActor(balancer)).start completion.await }