Skip to content

Instantly share code, notes, and snippets.

@yukinami
Created February 2, 2015 13:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yukinami/230dceea400d6548e7b3 to your computer and use it in GitHub Desktop.
Save yukinami/230dceea400d6548e7b3 to your computer and use it in GitHub Desktop.
AccountScope
package com.jumper.noodles.mobile.account;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import android.accounts.Account;
import android.accounts.AccountManager;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Module;
import org.roboguice.shaded.goole.common.base.Preconditions;
/**
* Custom scope that makes an authenticated GitHub account available by
* enforcing that the user is logged in before proceeding.
*/
public class AccountScope extends ScopeBase {
private static final Key<NoodlesAccount> NOODLES_ACCOUNT_KEY = Key
.get(NoodlesAccount.class);
@Inject
private AccountConfig config;
/**
* Create new module
*
* @return module
*/
public static Module module() {
return new AbstractModule() {
public void configure() {
AccountScope scope = new AccountScope();
bindScope(AccountScoped.class, scope);
bind(AccountScope.class).toInstance(scope);
bind(NOODLES_ACCOUNT_KEY).toProvider(
AccountScope.<NoodlesAccount>seededKeyProvider()).in(
scope);
}
};
}
private final ThreadLocal<NoodlesAccount> currentAccount = new ThreadLocal<NoodlesAccount>();
private final Map<NoodlesAccount, Map<Key<?>, Object>> scopeMaps = new ConcurrentHashMap<NoodlesAccount, Map<Key<?>, Object>>();
/**
* Enters scope using a GitHubAccount derived from the supplied account
*
* @param account
* @param accountManager
*/
public void enterWith(final Account account,
final AccountManager accountManager) {
enterWith(new NoodlesAccount(account, config.getAuthTokenType(), accountManager));
}
/**
* Enter scope with account
*
* @param account
*/
public void enterWith(final NoodlesAccount account) {
if (currentAccount.get() != null)
throw new IllegalStateException(
"A scoping block is already in progress");
currentAccount.set(account);
}
/**
* Exit scope
*/
public void exit() {
if (currentAccount.get() == null)
throw new IllegalStateException("No scoping block in progress");
currentAccount.remove();
}
@Override
protected <T> Map<Key<?>, Object> getScopedObjectMap(final Key<T> key) {
NoodlesAccount account = currentAccount.get();
if (account == null)
throw new IllegalStateException("Cannot access " + key
+ " outside of a scoping block");
Map<Key<?>, Object> scopeMap = scopeMaps.get(account);
if (scopeMap == null) {
scopeMap = new ConcurrentHashMap<Key<?>, Object>();
scopeMap.put(NOODLES_ACCOUNT_KEY, account);
scopeMaps.put(account, scopeMap);
}
return scopeMap;
}
public <T> void seed(Key<T> key, T value) {
Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);
Preconditions.checkState(!scopedObjects.containsKey(key), "A value for the key %s was " +
"already seeded in this scope. Old value: %s New value: %s", key,
scopedObjects.get(key), value);
scopedObjects.put(key, value);
}
public <T> void seed(Class<T> clazz, T value) {
seed(Key.get(clazz), value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment