Hi guys,
Vaughn Vernon asked me this morning if it would make sense to implement
Qi4j in Scala. I said no, but maybe Qi4j can use Scala classes directly
instead. So, having literally 0 experience with Scala I set out to try
and see what could be done.
... a couple of hours later ...
Short story: works great!
Longer story:
Because of how Scala translates "traits" into bytecode, I hade to create
a generic mixin that handles calls to Scala traits, and delegates them
appropriately. The "trait" is converted to one interface, and one class
with static methods. So, when the generic mixin is invoked on the
interface methods of the trait, I simply look up the corresponding
static method, and invoke it properly.
Example mixin declaration:
trait HelloWorldMixin2
{
def doMoreStuff(@MaxLength(10) name: String): String = "Hello "+name
}
Example composite declaration:
@Concerns(Array(classOf[HelloThereConcern]))
trait HelloWorldComposite
extends TransientComposite with HelloWorldMixin with HelloWorldMixin2
Example typed concern:
class HelloThereConcern
extends ConcernOf[HelloWorldMixin2] with HelloWorldMixin2
{
override def doMoreStuff(name: String) = next.doMoreStuff("there "+name);
}
And generic concern with filter:
@AppliesTo(Array(classOf[StringFilter]))
class ExclamationGenericConcern
extends GenericConcern
{
def invoke(composite: AnyRef, method: Method, args: Array[AnyRef]) =
next.invoke(composite, method, args)+"!"
}
class StringFilter
extends AppliesToFilter
{
def appliesTo(method: Method, mixin: Class[_], compositeType:
Class[_], fragmentClass: Class[_]) =
method.getReturnType.equals(classOf[String])
}
---
So that pretty much covers the domain model part. Usage from Java is
transparent, since it looks just like interfaces and classes. IntelliJ
auto-completion for the "doMoreStuff" method even works properly when
using the Scala plugin (I did the tests in Java+JUnit). Building in
Gradle is trivial since there's a plugin for that.
In short, AFAICT we now have support for Scala in Qi4j. The only
question is where to put the generic mixin that I wrote. Right now it's
just in a sample app. It could theoretically be promoted to Core API and
added to Composite, just like PropertyMixin, as I could get it to work
without any references to the Scala library, so that it works
out-of-the-box. Or, we could put it in a library. Either way is fine by me.
Thoughts on that?
/Rickard
_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev