In the context of Eclipse Databinding, there are quite a few Java classes that act as factories for IObservable
objects. For instance, there's BeanObservables
, PojoObservables
, EMFObservables
, etc., and they all implement a set of methods similar to
public static IObservableValue observeValue(Object target, String property)
Now if we were in the Scala world, each of those factories would probably be a singleton object implementing a common trait, say, IObservableFactory
, and I could, for instance, pass them around as implicit values to methods that would use them to create data bindings.
But as they are defined in Java, it seems I can do none of that. I can't write
val pojoObservableFact = PojoObservables
because PojoObservables
is not recognized as being a value.
Is there any way to make the compiler "instantiate" a singleton that would correspond to the PojoObservables
class in Scala? Or any workaround for it? I know I could write the singleton myself and forward all method calls, but this sounds a bit tedious.
Edit
To make it clearer: this is what I'm trying to do: define a method that creates the observable value using a passed factory.
def createObservable(fact: ObservableFactory, target: AnyRef, property: String) =
fact.observeValue(target, property)
but I wouldn't know how to define ObservableFactory
or how to actually pass PojoObservables
, a Java class with only static methods, to this createObservable
method.
If no-one else comes up with a working answer, I don't think it would be all that hard to write a code generator based on the method signatures.
will, for instance, pull out all the method signatures (for
String
in this case) as strings. Thenwill grab just the function signature with the return type split out front. Now
will get the argument signatures and name of the function, respectively. We then need to convert the primitive types, which is pretty easy since we just need to capitalize the first letter (save for void which becomes unit):
and finally you can put it all back together:
Now you have a bunch of Scala code that you can put (by hand) in an appropriate singleton.
(Varargs aren't working here, incidentally--you'd need to fix those if they were present. You can do this by going back to the
.isVarArgs
method from the method itself (not its string representation) and converting the last Array[X] into X* and then calling it asai: _*
.)The nice thing about this approach is that if there are common methods, you don't even need to use structural typing in order to pull them out--you can define your own trait that your wrapped methods inherit from! (And if you're especially ambitious, you can shoehorn almost-but-not-quite conforming methods to actually conform, e.g. to all have the same method name.)