177 lines
8.4 KiB
Java
177 lines
8.4 KiB
Java
|
package com.google.common.eventbus;
|
||
|
|
||
|
import com.google.common.base.MoreObjects;
|
||
|
import com.google.common.base.Objects;
|
||
|
import com.google.common.base.Preconditions;
|
||
|
import com.google.common.base.Throwables;
|
||
|
import com.google.common.cache.CacheBuilder;
|
||
|
import com.google.common.cache.CacheLoader;
|
||
|
import com.google.common.cache.LoadingCache;
|
||
|
import com.google.common.collect.HashMultimap;
|
||
|
import com.google.common.collect.ImmutableList;
|
||
|
import com.google.common.collect.ImmutableSet;
|
||
|
import com.google.common.collect.Iterators;
|
||
|
import com.google.common.collect.Lists;
|
||
|
import com.google.common.collect.Maps;
|
||
|
import com.google.common.collect.Multimap;
|
||
|
import com.google.common.collect.UnmodifiableIterator;
|
||
|
import com.google.common.primitives.Primitives;
|
||
|
import com.google.common.reflect.TypeToken;
|
||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||
|
import java.lang.reflect.Method;
|
||
|
import java.util.ArrayList;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.Collection;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Iterator;
|
||
|
import java.util.List;
|
||
|
import java.util.Map;
|
||
|
import java.util.Set;
|
||
|
import java.util.concurrent.ConcurrentMap;
|
||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public final class SubscriberRegistry {
|
||
|
private final EventBus bus;
|
||
|
private final ConcurrentMap<Class<?>, CopyOnWriteArraySet<Subscriber>> subscribers = Maps.newConcurrentMap();
|
||
|
private static final LoadingCache<Class<?>, ImmutableList<Method>> subscriberMethodsCache = CacheBuilder.newBuilder().weakKeys().build(new CacheLoader<Class<?>, ImmutableList<Method>>() { // from class: com.google.common.eventbus.SubscriberRegistry.1
|
||
|
@Override // com.google.common.cache.CacheLoader
|
||
|
public ImmutableList<Method> load(Class<?> cls) throws Exception {
|
||
|
return SubscriberRegistry.getAnnotatedMethodsNotCached(cls);
|
||
|
}
|
||
|
});
|
||
|
private static final LoadingCache<Class<?>, ImmutableSet<Class<?>>> flattenHierarchyCache = CacheBuilder.newBuilder().weakKeys().build(new CacheLoader<Class<?>, ImmutableSet<Class<?>>>() { // from class: com.google.common.eventbus.SubscriberRegistry.2
|
||
|
@Override // com.google.common.cache.CacheLoader
|
||
|
public ImmutableSet<Class<?>> load(Class<?> cls) {
|
||
|
return ImmutableSet.copyOf((Collection) TypeToken.of((Class) cls).getTypes().rawTypes());
|
||
|
}
|
||
|
});
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public SubscriberRegistry(EventBus eventBus) {
|
||
|
this.bus = (EventBus) Preconditions.checkNotNull(eventBus);
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public final void register(Object obj) {
|
||
|
for (Map.Entry<Class<?>, Collection<Subscriber>> entry : findAllSubscribers(obj).asMap().entrySet()) {
|
||
|
Class<?> key = entry.getKey();
|
||
|
Collection<Subscriber> value = entry.getValue();
|
||
|
CopyOnWriteArraySet<Subscriber> copyOnWriteArraySet = this.subscribers.get(key);
|
||
|
if (copyOnWriteArraySet == null) {
|
||
|
CopyOnWriteArraySet<Subscriber> copyOnWriteArraySet2 = new CopyOnWriteArraySet<>();
|
||
|
copyOnWriteArraySet = (CopyOnWriteArraySet) MoreObjects.firstNonNull(this.subscribers.putIfAbsent(key, copyOnWriteArraySet2), copyOnWriteArraySet2);
|
||
|
}
|
||
|
copyOnWriteArraySet.addAll(value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public final void unregister(Object obj) {
|
||
|
for (Map.Entry<Class<?>, Collection<Subscriber>> entry : findAllSubscribers(obj).asMap().entrySet()) {
|
||
|
Class<?> key = entry.getKey();
|
||
|
Collection<Subscriber> value = entry.getValue();
|
||
|
CopyOnWriteArraySet<Subscriber> copyOnWriteArraySet = this.subscribers.get(key);
|
||
|
if (copyOnWriteArraySet == null || !copyOnWriteArraySet.removeAll(value)) {
|
||
|
String valueOf = String.valueOf(obj);
|
||
|
StringBuilder sb = new StringBuilder(String.valueOf(valueOf).length() + 65);
|
||
|
sb.append("missing event subscriber for an annotated method. Is ");
|
||
|
sb.append(valueOf);
|
||
|
sb.append(" registered?");
|
||
|
throw new IllegalArgumentException(sb.toString());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
final Set<Subscriber> getSubscribersForTesting(Class<?> cls) {
|
||
|
return (Set) MoreObjects.firstNonNull(this.subscribers.get(cls), ImmutableSet.of());
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public final Iterator<Subscriber> getSubscribers(Object obj) {
|
||
|
ImmutableSet<Class<?>> flattenHierarchy = flattenHierarchy(obj.getClass());
|
||
|
ArrayList newArrayListWithCapacity = Lists.newArrayListWithCapacity(flattenHierarchy.size());
|
||
|
UnmodifiableIterator<Class<?>> it = flattenHierarchy.iterator();
|
||
|
while (it.hasNext()) {
|
||
|
CopyOnWriteArraySet<Subscriber> copyOnWriteArraySet = this.subscribers.get(it.next());
|
||
|
if (copyOnWriteArraySet != null) {
|
||
|
newArrayListWithCapacity.add(copyOnWriteArraySet.iterator());
|
||
|
}
|
||
|
}
|
||
|
return Iterators.concat(newArrayListWithCapacity.iterator());
|
||
|
}
|
||
|
|
||
|
private Multimap<Class<?>, Subscriber> findAllSubscribers(Object obj) {
|
||
|
HashMultimap create = HashMultimap.create();
|
||
|
UnmodifiableIterator<Method> it = getAnnotatedMethods(obj.getClass()).iterator();
|
||
|
while (it.hasNext()) {
|
||
|
Method next = it.next();
|
||
|
create.put(next.getParameterTypes()[0], Subscriber.create(this.bus, obj, next));
|
||
|
}
|
||
|
return create;
|
||
|
}
|
||
|
|
||
|
private static ImmutableList<Method> getAnnotatedMethods(Class<?> cls) {
|
||
|
try {
|
||
|
return subscriberMethodsCache.getUnchecked(cls);
|
||
|
} catch (UncheckedExecutionException e) {
|
||
|
Throwables.throwIfUnchecked(e.getCause());
|
||
|
throw e;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: private */
|
||
|
public static ImmutableList<Method> getAnnotatedMethodsNotCached(Class<?> cls) {
|
||
|
Set rawTypes = TypeToken.of((Class) cls).getTypes().rawTypes();
|
||
|
HashMap newHashMap = Maps.newHashMap();
|
||
|
Iterator it = rawTypes.iterator();
|
||
|
while (it.hasNext()) {
|
||
|
for (Method method : ((Class) it.next()).getDeclaredMethods()) {
|
||
|
if (method.isAnnotationPresent(Subscribe.class) && !method.isSynthetic()) {
|
||
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
||
|
Preconditions.checkArgument(parameterTypes.length == 1, "Method %s has @Subscribe annotation but has %s parameters. Subscriber methods must have exactly 1 parameter.", (Object) method, parameterTypes.length);
|
||
|
Preconditions.checkArgument(!parameterTypes[0].isPrimitive(), "@Subscribe method %s's parameter is %s. Subscriber methods cannot accept primitives. Consider changing the parameter to %s.", method, parameterTypes[0].getName(), Primitives.wrap(parameterTypes[0]).getSimpleName());
|
||
|
MethodIdentifier methodIdentifier = new MethodIdentifier(method);
|
||
|
if (!newHashMap.containsKey(methodIdentifier)) {
|
||
|
newHashMap.put(methodIdentifier, method);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return ImmutableList.copyOf(newHashMap.values());
|
||
|
}
|
||
|
|
||
|
static ImmutableSet<Class<?>> flattenHierarchy(Class<?> cls) {
|
||
|
try {
|
||
|
return flattenHierarchyCache.getUnchecked(cls);
|
||
|
} catch (UncheckedExecutionException e) {
|
||
|
throw Throwables.propagate(e.getCause());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* loaded from: classes2.dex */
|
||
|
public static final class MethodIdentifier {
|
||
|
private final String name;
|
||
|
private final List<Class<?>> parameterTypes;
|
||
|
|
||
|
MethodIdentifier(Method method) {
|
||
|
this.name = method.getName();
|
||
|
this.parameterTypes = Arrays.asList(method.getParameterTypes());
|
||
|
}
|
||
|
|
||
|
public final int hashCode() {
|
||
|
return Objects.hashCode(this.name, this.parameterTypes);
|
||
|
}
|
||
|
|
||
|
public final boolean equals(Object obj) {
|
||
|
if (!(obj instanceof MethodIdentifier)) {
|
||
|
return false;
|
||
|
}
|
||
|
MethodIdentifier methodIdentifier = (MethodIdentifier) obj;
|
||
|
return this.name.equals(methodIdentifier.name) && this.parameterTypes.equals(methodIdentifier.parameterTypes);
|
||
|
}
|
||
|
}
|
||
|
}
|