diff --git a/akka-actor/src/main/scala/util/JavaAPI.scala b/akka-actor/src/main/scala/util/JavaAPI.scala index 248eaf7fbe..adf074aad9 100644 --- a/akka-actor/src/main/scala/util/JavaAPI.scala +++ b/akka-actor/src/main/scala/util/JavaAPI.scala @@ -1,23 +1,21 @@ package se.scalablesolutions.akka.util object JavaAPI { - /** A Function interface - * Used to create first-class-functions is Java (sort of) - * Java API + /** + * A Function interface. Used to create first-class-functions is Java (sort of). */ 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 + * An executable piece of code that takes no parameters and doesn't return any value. */ trait SideEffect { def apply: Unit @@ -31,45 +29,53 @@ object JavaAPI { * Java API */ sealed abstract class Option[A] extends java.lang.Iterable[A] { + import scala.collection.JavaConversions._ + def get: A - def isDefined: Boolean + def isEmpty: Boolean + def isDefined = !isEmpty def asScala: scala.Option[A] + def iterator = if (isEmpty) Iterator.empty else Iterator.single(get) } - /** - * 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._ + object Option { + /** + * Option factory that creates Some + */ + def some[A](v: A): Option[A] = Some(v) - def get = v - def iterator = Iterator.single(v) - def isDefined = true - def asScala = scala.Some(v) + /** + * Option factory that creates None + */ + def none[A] = None.asInstanceOf[Option[A]] + + /** + * Option factory that creates None if + * v is null, Some(v) otherwise. + */ + def option[A](v: A): Option[A] = if (v == null) none else some(v) + + /** + * Class Some[A] represents existing values of type + * A. + */ + private final case class Some[A](v: A) extends Option[A] { + def get = v + def isEmpty = false + def asScala = scala.Some(v) + } + + /** + * This case object represents non-existent values. + */ + private case object None extends Option[Nothing] { + def get = throw new NoSuchElementException("None.get") + def isEmpty = true + def asScala = scala.None + } + + implicit def java2ScalaOption[A](o: Option[A]): scala.Option[A] = o.asScala + implicit def scala2JavaOption[A](o: scala.Option[A]): Option[A] = option(o.get) } - - /** - * 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 = Iterator.empty - def isDefined = false - def asScala = scala.None - } - - def some[A](v: A) = Some(v) - def none[A] = None[A] - - implicit def java2ScalaOption[A](o: Option[A]): scala.Option[A] = o.asScala - implicit def scala2JavaOption[A](o: scala.Option[A]): Option[A] = - if (o.isDefined) Some(o.get) else None[A] } diff --git a/akka-camel/src/main/scala/CamelContextLifecycle.scala b/akka-camel/src/main/scala/CamelContextLifecycle.scala index 8348ba4590..7aadac8ac1 100644 --- a/akka-camel/src/main/scala/CamelContextLifecycle.scala +++ b/akka-camel/src/main/scala/CamelContextLifecycle.scala @@ -1,5 +1,5 @@ /** - * Copyright (C) 2009-2010 Scalable Solutions AB + * Copyright (C) 2009-2010 Scalable Solutions AB */ package se.scalablesolutions.akka.camel @@ -19,7 +19,7 @@ import se.scalablesolutions.akka.util.JavaAPI.{Option => JOption} * * @author Martin Krasser */ -trait CamelContextLifecycle extends CamelContextLifecycleJavaAPI with Logging { +trait CamelContextLifecycle extends Logging { // TODO: enforce correct state transitions // valid: init -> start -> stop -> init ... @@ -41,25 +41,65 @@ trait CamelContextLifecycle extends CamelContextLifecycleJavaAPI with Logging { private[camel] var typedActorRegistry: Map[String, AnyRef] = _ /** - * Returns Some(CamelContext) if CamelContextLifecycle - * has been initialized, otherwise None. + * Returns Some(CamelContext) (containing the current CamelContext) + * if CamelContextLifecycle has been initialized, otherwise None. */ - protected def context: Option[CamelContext] = _context + def context: Option[CamelContext] = _context /** - * Returns Some(ProducerTemplate) if CamelContextLifecycle - * has been initialized, otherwise None. + * Returns Some(ProducerTemplate) (containing the current ProducerTemplate) + * if CamelContextLifecycle has been initialized, otherwise None. */ - protected def template: Option[ProducerTemplate] = _template + def template: Option[ProducerTemplate] = _template + /** + * Returns Some(CamelContext) (containing the current CamelContext) + * if CamelContextLifecycle has been initialized, otherwise None. + *

+ * Java API. + */ + def getContext: JOption[CamelContext] = context + + /** + * Returns Some(ProducerTemplate) (containing the current ProducerTemplate) + * if CamelContextLifecycle has been initialized, otherwise None. + *

+ * Java API. + */ + def getTemplate: JOption[ProducerTemplate] = template + + /** + * Returns the current CamelContext if this CamelContextLifecycle + * has been initialized, otherwise throws an IllegalStateException. + */ def mandatoryContext = if (context.isDefined) context.get else throw new IllegalStateException("no current CamelContext") + /** + * Returns the current ProducerTemplate if this CamelContextLifecycle + * has been initialized, otherwise throws an IllegalStateException. + */ def mandatoryTemplate = if (template.isDefined) template.get else throw new IllegalStateException("no current ProducerTemplate") - + + /** + * Returns the current CamelContext if this CamelContextLifecycle + * has been initialized, otherwise throws an IllegalStateException. + *

+ * Java API. + */ + def getMandatoryContext = mandatoryContext + + /** + * Returns the current ProducerTemplate if this CamelContextLifecycle + * has been initialized, otherwise throws an IllegalStateException. + *

+ * Java API. + */ + def getMandatoryTemplate = mandatoryTemplate + def initialized = _initialized def started = _started @@ -89,6 +129,7 @@ trait CamelContextLifecycle extends CamelContextLifecycleJavaAPI with Logging { t.stop c.stop _started = false + _initialized = false log.info("Camel context stopped") } } @@ -120,38 +161,42 @@ trait CamelContextLifecycle extends CamelContextLifecycleJavaAPI with Logging { } } -/** - * Java API for CamelContextLifecycle. - * - * @author Martin Krasser - */ -trait CamelContextLifecycleJavaAPI { this: CamelContextLifecycle => - /** - * Returns Some(CamelContext) if CamelContextLifecycle - * has been initialized, otherwise None. - */ - def getContext: JOption[CamelContext] = context - - /** - * Returns Some(ProducerTemplate) if CamelContextLifecycle - * has been initialized, otherwise None. - */ - def getTemplate: JOption[ProducerTemplate] = template -} - /** * Manages a global CamelContext and an associated ProducerTemplate. */ -object CamelContextManager extends CamelContextLifecycle with CamelContextLifecycleJavaAPI { - /** - * Returns Some(CamelContext) if CamelContextLifecycle - * has been initialized, otherwise None. - */ - override def context: Option[CamelContext] = super.context +object CamelContextManager extends CamelContextLifecycle { + + // ----------------------------------------------------- + // The inherited getters aren't statically accessible + // from Java. Therefore, they are redefined here. + // TODO: investigate if this is a Scala bug. + // ----------------------------------------------------- /** - * Returns Some(ProducerTemplate) if CamelContextLifecycle - * has been initialized, otherwise None. + * see CamelContextLifecycle.getContext + *

+ * Java API. */ - override def template: Option[ProducerTemplate] = super.template + override def getContext: JOption[CamelContext] = super.getContext + + /** + * see CamelContextLifecycle.getTemplate + *

+ * Java API. + */ + override def getTemplate: JOption[ProducerTemplate] = super.getTemplate + + /** + * see CamelContextLifecycle.getMandatoryContext + *

+ * Java API. + */ + override def getMandatoryContext = super.getMandatoryContext + + /** + * see CamelContextLifecycle.getMandatoryTemplate + *

+ * Java API. + */ + override def getMandatoryTemplate = super.getMandatoryTemplate } diff --git a/akka-camel/src/main/scala/CamelService.scala b/akka-camel/src/main/scala/CamelService.scala index 3d6705da00..8509c10b64 100644 --- a/akka-camel/src/main/scala/CamelService.scala +++ b/akka-camel/src/main/scala/CamelService.scala @@ -10,8 +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.{Logging, Bootable} import se.scalablesolutions.akka.util.JavaAPI.{Option => JOption} +import se.scalablesolutions.akka.util.{Logging, Bootable} /** * Publishes (untyped) consumer actors and typed consumer actors via Camel endpoints. Actors @@ -74,7 +74,7 @@ trait CamelService extends Bootable with Logging { // Register this instance as current CamelService and return it CamelServiceManager.register(this) - CamelServiceManager.service.get + CamelServiceManager.mandatoryService } /** @@ -116,7 +116,7 @@ trait CamelService extends Bootable with Logging { * * @author Martin Krasser */ -object CamelServiceManager extends CamelServiceManagerJavaAPI { +object CamelServiceManager { /** * The current (optional) CamelService. Is defined when a CamelService has been started. @@ -140,12 +140,34 @@ object CamelServiceManager extends CamelServiceManagerJavaAPI { def stopCamelService = for (s <- service) s.stop /** - * Returns Some(CamelService) if CamelService + * Returns Some(CamelService) if this CamelService * has been started, None otherwise. */ def service = _current - // TODO: add mandatoryService (throwing exception if service is not defined) + /** + * Returns the current CamelService if CamelService + * has been started, otherwise throws an IllegalStateException. + *

+ * Java API + */ + def getService: JOption[CamelService] = CamelServiceManager.service + + /** + * Returns Some(CamelService) (containing the current CamelService) + * if this CamelServicehas been started, None otherwise. + */ + def mandatoryService = + if (_current.isDefined) _current.get + else throw new IllegalStateException("co current Camel service") + + /** + * Returns Some(CamelService) (containing the current CamelService) + * if this CamelServicehas been started, None otherwise. + *

+ * Java API + */ + def getMandatoryService = mandatoryService private[camel] def register(service: CamelService) = if (_current.isDefined) throw new IllegalStateException("current CamelService already registered") @@ -156,21 +178,6 @@ object CamelServiceManager extends CamelServiceManagerJavaAPI { else throw new IllegalStateException("only current CamelService can be unregistered") } -/** - * Java API for CamelServiceManager. - * - * @author Martin Krasser - */ -trait CamelServiceManagerJavaAPI { - /** - * Returns Some(CamelService) if CamelService - * has been started, None otherwise. - *

- * Java API - */ - def getService: JOption[CamelService] = CamelServiceManager.service -} - /** * @author Martin Krasser */ diff --git a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/SampleUntypedForwardingProducer.java b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/SampleUntypedForwardingProducer.java index ec2f7eb560..bfa34f42e5 100644 --- a/akka-camel/src/test/java/se/scalablesolutions/akka/camel/SampleUntypedForwardingProducer.java +++ b/akka-camel/src/test/java/se/scalablesolutions/akka/camel/SampleUntypedForwardingProducer.java @@ -13,6 +13,6 @@ public class SampleUntypedForwardingProducer extends UntypedProducerActor { public void onReceiveAfterProduce(Object message) { Message msg = (Message)message; String body = msg.bodyAs(String.class); - CamelContextManager.mandatoryTemplate().sendBody("direct:forward-test-1", body); + CamelContextManager.getMandatoryTemplate().sendBody("direct:forward-test-1", body); } } diff --git a/akka-camel/src/test/scala/CamelServiceManagerTest.scala b/akka-camel/src/test/scala/CamelServiceManagerTest.scala index 8f7916d574..712ffec70b 100644 --- a/akka-camel/src/test/scala/CamelServiceManagerTest.scala +++ b/akka-camel/src/test/scala/CamelServiceManagerTest.scala @@ -19,7 +19,7 @@ class CamelServiceManagerTest extends WordSpec with BeforeAndAfterAll with MustM "the startCamelService method been has been called" must { "have registered the started CamelService instance" in { val service = CamelServiceManager.startCamelService - CamelServiceManager.service.get must be theSameInstanceAs (service) + CamelServiceManager.mandatoryService must be theSameInstanceAs (service) } } "the stopCamelService method been has been called" must { @@ -35,7 +35,7 @@ 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.get must be theSameInstanceAs (service) + CamelServiceManager.mandatoryService must be theSameInstanceAs (service) } } "the current CamelService instance has been stopped externally" must { diff --git a/akka-camel/src/test/scala/RemoteConsumerTest.scala b/akka-camel/src/test/scala/RemoteConsumerTest.scala index 393f7a9a53..2218aac25a 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.get.expectEndpointActivationCount(1) + var latch = mandatoryService.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.get.expectEndpointActivationCount(1) + var latch = mandatoryService.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.get.expectEndpointActivationCount(1) + var latch = mandatoryService.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 5335c47664..2ecccb1e02 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" == mandatoryContext.createProducerTemplate.requestBody("direct:test", "msg1")) // set expectations on upcoming endpoint activation - val activation = service.get.expectEndpointActivationCount(1) + val activation = mandatoryService.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.get.expectEndpointActivationCount(2) + val completion = mandatoryService.expectEndpointActivationCount(2) val jmsUri = "jms:topic:test" // Wire publisher and consumer using a JMS topic