Chris Lee <chris.lee <at> leeprinting.com> writes:
>
> Jonathan Hall <jonrhall <at> gmail.com> writes:
>
> > Maybe down to: "Important Context Changes" dated 29/07/2008
> >
> > "- the Context instance given to an application (or any Restlet
> > actually) will be the one effectively used. If parameters are set, they
> > will be directly and permanently accessible. If none is given, a null
> > context will be returned by getContext(), no default context will be
> > returned anymore."
>
> Thanks! I changed the line from Context.getCurrent() to
> Application.getCurrent().getContext() and at first blush it seems to work.
> I'll
> continue working with it to make sure it bears up and post the new
> FinderFactoryModule.java with Tim's update and this tweak.
>
> Chris Lee
>
>
I don't see any way to attach a fil here, but below you can find a listing for
FinderFactoryModule.java with Tim's recommended updates and the workaround I am
using. I hope it helps someone. Thanks for all your help!
FinderFactoryModule.java:
package net.peierls.restlet.util;
import static java.util.Collections.emptyList;
import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Finder;
import org.restlet.Handler;
import org.restlet.data.Request;
import org.restlet.data.Response;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
/**
* A Guice module that doubles as a factory for creating Finders that look up
* Handler or Resource instances from a given class or Guice Key. On first use
* of these Finders, if the module hasn't been used to create an Injector, this
* module creates its own Injector.
*/
public class FinderFactoryModule extends AbstractModule implements
FinderFactory {
/**
* Creates a FinderFactoryModule that will install the given modules.
*/
public FinderFactoryModule(Module... modules) {
this.moduleArray = modules;
this.modules = emptyList();
}
/**
* Creates a FinderFactoryModule that will install the given modules.
*/
public FinderFactoryModule(Iterable<Module> modules) {
this.moduleArray = new Module[0];
this.modules = modules;
}
//
// FinderFactory methods
//
public Finder finderFor(Key<? extends Handler> key) {
return new KeyFinder(key);
}
public Finder finderFor(Class<? extends Handler> cls) {
return new KeyFinder(Key.get(cls));
}
/**
* This method must be called by any method that overrides it.
*/
@Override
protected final void configure() {
if (injector != null) {
throw new IllegalStateException("can't reconfigure with existing
Injector");
}
if (!alreadyBound.get()) {
alreadyBound.set(true);
bind(Context.class).toProvider(newContextProvider());
bind(Request.class).toProvider(newRequestProvider());
bind(Response.class).toProvider(newResponseProvider());
bind(FinderFactory.class).toInstance(this);
}
for (Module module : moduleArray)
install(module);
for (Module module : modules)
install(module);
}
/**
* Creates a Provider for the Context. This can be overridden to supply a
* Context in a customized fashion.
*/
protected Provider<Context> newContextProvider() {
return new Provider<Context>() {
public Context get() {
return Application.getCurrent().getContext();
}
};
}
/**
* Creates a Provider for the Request. This can be overridden to supply a
* Request in a customized fashion.
*/
protected Provider<Request> newRequestProvider() {
return new Provider<Request>() {
public Request get() {
return Request.getCurrent();
}
};
}
/**
* Creates a Provider for the Response. This can be overridden to supply a
* Response in a customized fashion.
*/
protected Provider<Response> newResponseProvider() {
return new Provider<Response>() {
public Response get() {
return Response.getCurrent();
}
};
}
class KeyFinder extends Finder {
private final Key<? extends Handler> key;
KeyFinder(Key<? extends Handler> key) {
this.key = key;
}
@Override
protected Handler findTarget(Request request, Response response) {
return getInjector().getInstance(key);
}
private Injector getInjector() {
Injector inj = injector;
if (inj == null) {
synchronized (FinderFactoryModule.this) {
inj = injector;
if (inj == null) {
inj = Guice.createInjector(FinderFactoryModule.this);
}
}
}
return inj;
}
}
private final Module[] moduleArray;
private final Iterable<Module> modules;
@Inject
private volatile Injector injector;
@SuppressWarnings("unused")
@Inject
private void clearAlreadyBound() {
alreadyBound.set(false);
}
private static ThreadLocal<Boolean> alreadyBound =
new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return false;
}
};
}