use of com.google.gerrit.extensions.registration.ReloadableRegistrationHandle in project gerrit by GerritCodeReview.
the class PluginGuiceEnvironment method reattachSet.
private void reattachSet(ListMultimap<TypeLiteral<?>, ReloadableRegistrationHandle<?>> oldHandles, Map<TypeLiteral<?>, DynamicSet<?>> sets, @Nullable Injector src, Plugin newPlugin) {
if (src == null || sets == null || sets.isEmpty()) {
return;
}
for (Map.Entry<TypeLiteral<?>, DynamicSet<?>> e : sets.entrySet()) {
@SuppressWarnings("unchecked") TypeLiteral<Object> type = (TypeLiteral<Object>) e.getKey();
@SuppressWarnings("unchecked") DynamicSet<Object> set = (DynamicSet<Object>) e.getValue();
// Index all old handles that match this DynamicSet<T> keyed by
// annotations. Ignore the unique annotations, thereby favoring
// the @Named annotations or some other non-unique naming.
Map<Annotation, ReloadableRegistrationHandle<?>> am = new HashMap<>();
List<ReloadableRegistrationHandle<?>> old = oldHandles.get(type);
Iterator<ReloadableRegistrationHandle<?>> oi = old.iterator();
while (oi.hasNext()) {
ReloadableRegistrationHandle<?> h = oi.next();
Annotation a = h.getKey().getAnnotation();
if (a != null && !UNIQUE_ANNOTATION.isInstance(a)) {
am.put(a, h);
oi.remove();
}
}
// Replace old handles with new bindings, favoring cases where there
// is an exact match on an @Named annotation. If there is no match
// pick any handle and replace it. We generally expect only one
// handle of each DynamicSet type when using unique annotations, but
// possibly multiple ones if @Named was used. Plugin authors that want
// atomic replacement across reloads should use @Named annotations with
// stable names that do not change across plugin versions to ensure the
// handles are swapped correctly.
oi = old.iterator();
for (Binding<?> binding : bindings(src, type)) {
@SuppressWarnings("unchecked") Binding<Object> b = (Binding<Object>) binding;
Key<Object> key = b.getKey();
if (key.getAnnotation() == null) {
continue;
}
@SuppressWarnings("unchecked") ReloadableRegistrationHandle<Object> h1 = (ReloadableRegistrationHandle<Object>) am.remove(key.getAnnotation());
if (h1 != null) {
replace(newPlugin, h1, b);
} else if (oi.hasNext()) {
@SuppressWarnings("unchecked") ReloadableRegistrationHandle<Object> h2 = (ReloadableRegistrationHandle<Object>) oi.next();
oi.remove();
replace(newPlugin, h2, b);
} else {
newPlugin.add(set.add(b.getKey(), b.getProvider()));
}
}
}
}
use of com.google.gerrit.extensions.registration.ReloadableRegistrationHandle in project gerrit by GerritCodeReview.
the class PluginGuiceEnvironment method reattachMap.
private void reattachMap(ListMultimap<TypeLiteral<?>, ReloadableRegistrationHandle<?>> oldHandles, Map<TypeLiteral<?>, DynamicMap<?>> maps, @Nullable Injector src, Plugin newPlugin) {
if (src == null || maps == null || maps.isEmpty()) {
return;
}
for (Map.Entry<TypeLiteral<?>, DynamicMap<?>> e : maps.entrySet()) {
@SuppressWarnings("unchecked") TypeLiteral<Object> type = (TypeLiteral<Object>) e.getKey();
@SuppressWarnings("unchecked") PrivateInternals_DynamicMapImpl<Object> map = (PrivateInternals_DynamicMapImpl<Object>) e.getValue();
Map<Annotation, ReloadableRegistrationHandle<?>> am = new HashMap<>();
for (ReloadableRegistrationHandle<?> h : oldHandles.get(type)) {
Annotation a = h.getKey().getAnnotation();
if (a != null && !UNIQUE_ANNOTATION.isInstance(a)) {
am.put(a, h);
}
}
for (Binding<?> binding : bindings(src, e.getKey())) {
@SuppressWarnings("unchecked") Binding<Object> b = (Binding<Object>) binding;
Key<Object> key = b.getKey();
if (key.getAnnotation() == null) {
continue;
}
@SuppressWarnings("unchecked") ReloadableRegistrationHandle<Object> h = (ReloadableRegistrationHandle<Object>) am.remove(key.getAnnotation());
if (h != null) {
replace(newPlugin, h, b);
oldHandles.remove(type, h);
} else {
newPlugin.add(map.put(newPlugin.getName(), b.getKey(), b.getProvider()));
}
}
}
}
use of com.google.gerrit.extensions.registration.ReloadableRegistrationHandle in project gerrit by GerritCodeReview.
the class PluginGuiceEnvironment method onReloadPlugin.
void onReloadPlugin(Plugin oldPlugin, Plugin newPlugin) {
// Index all old registrations by the raw type. These may be replaced
// during the reattach calls below. Any that are not replaced will be
// removed when the old plugin does its stop routine.
ListMultimap<TypeLiteral<?>, ReloadableRegistrationHandle<?>> old = LinkedListMultimap.create();
for (ReloadableRegistrationHandle<?> h : oldPlugin.getReloadableHandles()) {
old.put(h.getKey().getTypeLiteral(), h);
}
RequestContext oldContext = enter(newPlugin);
try {
reattachMap(old, sysMaps, newPlugin.getSysInjector(), newPlugin);
reattachMap(old, sshMaps, newPlugin.getSshInjector(), newPlugin);
reattachMap(old, httpMaps, newPlugin.getHttpInjector(), newPlugin);
reattachSet(old, sysSets, newPlugin.getSysInjector(), newPlugin);
reattachSet(old, sshSets, newPlugin.getSshInjector(), newPlugin);
reattachSet(old, httpSets, newPlugin.getHttpInjector(), newPlugin);
reattachItem(old, sysItems, newPlugin.getSysInjector(), newPlugin);
reattachItem(old, sshItems, newPlugin.getSshInjector(), newPlugin);
reattachItem(old, httpItems, newPlugin.getHttpInjector(), newPlugin);
} finally {
exit(oldContext);
}
for (ReloadPluginListener l : onReload) {
l.onReloadPlugin(oldPlugin, newPlugin);
}
}
Aggregations