package org.togglz.appengine.repository; import javax.inject.Inject; import javax.inject.Named; import org.togglz.core.Feature; import org.togglz.core.repository.FeatureState; import org.togglz.core.repository.StateRepository; import com.google.appengine.api.NamespaceManager; import com.google.common.base.Preconditions; /** * Decorates the given StateRepository enforcing its operations to run within a given namespace. * Uses GAE's {@link NamespaceManager} to enforce the given namespace. * * @author Fábio Franco Uechi */ public class FixedNamespaceStateRepository implements StateRepository { private final String namespace; private final StateRepository decorated; @Inject public FixedNamespaceStateRepository(@Named("togglzFixedNamespace") String namespace, @Named("togglzFixedNamespace") StateRepository decorated) { this.decorated = Preconditions.checkNotNull(decorated); NamespaceManager.validateNamespace(namespace); this.namespace = namespace; } @Override public FeatureState getFeatureState(final Feature feature) { return withinNamespace(namespace, new Work<FeatureState> () { @Override public FeatureState run() { return decorated.getFeatureState(feature); } }); } @Override public void setFeatureState(final FeatureState featureState) { withinNamespace(namespace, new VoidWork() { @Override void vrun() { decorated.setFeatureState(featureState); } }); } static interface Work<T> { public T run(); } static abstract class VoidWork implements Work<Void> { @Override public Void run() { vrun(); return null; } abstract void vrun(); } public static <R> R withinNamespace(String namespace, Work<R> work) { String oldNamespace = NamespaceManager.get(); NamespaceManager.set(namespace); try { R r = work.run(); return r; } finally { NamespaceManager.set(oldNamespace); } } }