0

The following Java code sets up a Guice binding. It uses an anonymous subclass of AbstractModule that provides an implementation of configure to set the bindings, and anonymous subclasses of TypeLiteral to create a binding of Map to HashMap for specific type parameters (as described here).

injector = Guice.createInjector(new AbstractModule() {
    @Override protected void configure() {
        bind(new TypeLiteral<Map<String, Event>>() {})
            .to(new TypeLiteral<HashMap<String, Event>>() {});
    }
});

How could I write this in Xtend?

As far as I can see, Xtend doesn't support implementing anonymous classes or nested classes (they aren't mentioned in the doc and I haven't been able to guess a working syntax). So I would have to define my AbstractModule and each of my TypeLiteral implementations in separate Xtend files... not very terse. Am I missing an Xtend or a Guice trick to make this work well?

Community
  • 1
  • 1
rewbs
  • 1,958
  • 4
  • 22
  • 34

3 Answers3

1

what about intoducing a real class instead of a anonymous inner one?

Christian Dietrich
  • 11,778
  • 4
  • 24
  • 32
  • Hi Christian - that's a good idea and is my current approach. However, that real class has to stay in Java, else I'd also have to declare real classes for all the TypeLiteral implementations as well (in practice my code has more than the 2 shown in the sample above). I'm interested in whether there's an Xtend solution, or a different Guice API that would make the problem go away. – rewbs Nov 20 '11 at 11:37
  • 1
    let me quote the xtend homepage: *Xtend is not meant to replace Java all together but to be a convenient alternative in situations where Java doesn't shine. * i guess guice modules is a thing not to meant to be done in xtend – Christian Dietrich Nov 20 '11 at 14:32
1

You could use a closure to implement the module interface:

injector = Guice.createInjector [ bind(typeof(SomeType)).to(typeof(AnImplementation)) ]

However, this will not solve the problem for the type literals. You'd have to use Java for that one, but I think it will not hurt.

Sebastian Zarnekow
  • 6,609
  • 20
  • 23
0

On a related note, you can use an Xtend closure to implement Guice's Provider interface.

For example, calling IResourceScopeCache.get in Java:

@Inject
private IResourceScopeCache cache;

public EvaluatedResource getEvaluatedResource(EObject object) {
    final Resource resource = object.eResource();
    return cache.get("key", resource, new Provider<Object>() {
        public Object get() {
            return evaluate(resource);
        }
    });
}

public EvaluatedResource evaluate(Resource resource) {
    ...; // create EvaluatedResource evaluatedResource
    return evaluatedResource; // return it
}

in Xtend becomes:

@Inject
IResourceScopeCache cache

def getEvaluatedResource(EObject object) {
    val resource = object.eResource
    cache.get("key", resource, [|evaluate(resource)])
}

def evaluate(Resource resource) {
    ... // create EvaluatedResource evaluatedResource
    evaluatedResource // return it
}

The trick is that [|...] is a function with zero parameters, in this case Provider.get().

Jon
  • 398
  • 1
  • 11