Add DynamicItem for extension points with one implementation
Some extension points should only have one implementation provided, such as a provider of avatar images. In this case it doesn't make sense to have multiple providers. For this use-case we need DynamicItem. Change-Id: If5166c3f42c5619daea56d79dea8feb70f9ee084
This commit is contained in:
committed by
Shawn Pearce
parent
095a25143c
commit
ae984a98e2
@@ -13,6 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.gerrit.server.plugins;
|
||||
|
||||
import static com.google.gerrit.extensions.registration.PrivateInternals_DynamicTypes.dynamicItemsOf;
|
||||
import static com.google.gerrit.extensions.registration.PrivateInternals_DynamicTypes.dynamicMapsOf;
|
||||
import static com.google.gerrit.extensions.registration.PrivateInternals_DynamicTypes.dynamicSetsOf;
|
||||
|
||||
@@ -22,6 +24,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gerrit.extensions.events.LifecycleListener;
|
||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||
import com.google.gerrit.extensions.registration.DynamicMap;
|
||||
import com.google.gerrit.extensions.registration.DynamicSet;
|
||||
import com.google.gerrit.extensions.registration.PrivateInternals_DynamicMapImpl;
|
||||
@@ -74,6 +77,8 @@ public class PluginGuiceEnvironment {
|
||||
private Provider<ModuleGenerator> sshGen;
|
||||
private Provider<ModuleGenerator> httpGen;
|
||||
|
||||
private Map<TypeLiteral<?>, DynamicItem<?>> sysItems;
|
||||
|
||||
private Map<TypeLiteral<?>, DynamicSet<?>> sysSets;
|
||||
private Map<TypeLiteral<?>, DynamicSet<?>> sshSets;
|
||||
private Map<TypeLiteral<?>, DynamicSet<?>> httpSets;
|
||||
@@ -98,6 +103,7 @@ public class PluginGuiceEnvironment {
|
||||
onReload = new CopyOnWriteArrayList<ReloadPluginListener>();
|
||||
onReload.addAll(listeners(sysInjector, ReloadPluginListener.class));
|
||||
|
||||
sysItems = dynamicItemsOf(sysInjector);
|
||||
sysSets = dynamicSetsOf(sysInjector);
|
||||
sysMaps = dynamicMapsOf(sysInjector);
|
||||
}
|
||||
@@ -106,6 +112,10 @@ public class PluginGuiceEnvironment {
|
||||
return srvInfo;
|
||||
}
|
||||
|
||||
boolean hasDynamicItem(TypeLiteral<?> type) {
|
||||
return sysItems.containsKey(type);
|
||||
}
|
||||
|
||||
boolean hasDynamicSet(TypeLiteral<?> type) {
|
||||
return sysSets.containsKey(type)
|
||||
|| (sshSets != null && sshSets.containsKey(type))
|
||||
@@ -182,6 +192,8 @@ public class PluginGuiceEnvironment {
|
||||
l.onStartPlugin(plugin);
|
||||
}
|
||||
|
||||
attachItem(sysItems, plugin.getSysInjector(), plugin);
|
||||
|
||||
attachSet(sysSets, plugin.getSysInjector(), plugin);
|
||||
attachSet(sshSets, plugin.getSshInjector(), plugin);
|
||||
attachSet(httpSets, plugin.getHttpInjector(), plugin);
|
||||
@@ -191,6 +203,15 @@ public class PluginGuiceEnvironment {
|
||||
attachMap(httpMaps, plugin.getHttpInjector(), plugin);
|
||||
}
|
||||
|
||||
private void attachItem(Map<TypeLiteral<?>, DynamicItem<?>> items,
|
||||
@Nullable Injector src,
|
||||
Plugin plugin) {
|
||||
for (RegistrationHandle h : PrivateInternals_DynamicTypes
|
||||
.attachItems(src, items, plugin.getName())) {
|
||||
plugin.add(h);
|
||||
}
|
||||
}
|
||||
|
||||
private void attachSet(Map<TypeLiteral<?>, DynamicSet<?>> sets,
|
||||
@Nullable Injector src,
|
||||
Plugin plugin) {
|
||||
@@ -230,6 +251,8 @@ public class PluginGuiceEnvironment {
|
||||
reattachSet(old, sysSets, newPlugin.getSysInjector(), newPlugin);
|
||||
reattachSet(old, sshSets, newPlugin.getSshInjector(), newPlugin);
|
||||
reattachSet(old, httpSets, newPlugin.getHttpInjector(), newPlugin);
|
||||
|
||||
reattachItem(old, sysItems, newPlugin.getSysInjector(), newPlugin);
|
||||
}
|
||||
|
||||
private void reattachMap(
|
||||
@@ -350,6 +373,41 @@ public class PluginGuiceEnvironment {
|
||||
}
|
||||
}
|
||||
}
|
||||
private void reattachItem(
|
||||
ListMultimap<TypeLiteral<?>, ReloadableRegistrationHandle<?>> oldHandles,
|
||||
Map<TypeLiteral<?>, DynamicItem<?>> items,
|
||||
@Nullable Injector src,
|
||||
Plugin newPlugin) {
|
||||
if (src == null || items == null || items.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<TypeLiteral<?>, DynamicItem<?>> e : items.entrySet()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
TypeLiteral<Object> type = (TypeLiteral<Object>) e.getKey();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DynamicItem<Object> item = (DynamicItem<Object>) e.getValue();
|
||||
|
||||
Iterator<ReloadableRegistrationHandle<?>> oi =
|
||||
oldHandles.get(type).iterator();
|
||||
|
||||
for (Binding<?> binding : bindings(src, type)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Binding<Object> b = (Binding<Object>) binding;
|
||||
if (oi.hasNext()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ReloadableRegistrationHandle<Object> h =
|
||||
(ReloadableRegistrationHandle<Object>) oi.next();
|
||||
oi.remove();
|
||||
replace(newPlugin, h, b);
|
||||
} else {
|
||||
newPlugin.add(item.set(b.getKey(), b.getProvider(),
|
||||
newPlugin.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> void replace(Plugin newPlugin,
|
||||
ReloadableRegistrationHandle<T> h, Binding<T> b) {
|
||||
|
||||
Reference in New Issue
Block a user