Created
February 2, 2015 13:47
-
-
Save yukinami/230dceea400d6548e7b3 to your computer and use it in GitHub Desktop.
AccountScope
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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