blob: e606079345120e3be9033a0291482f55e84d3fa9 [file] [log] [blame]
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.registration;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.inject.Binding;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** <b>DO NOT USE</b> */
public class PrivateInternals_DynamicTypes {
public static Map<TypeLiteral<?>, DynamicItem<?>> dynamicItemsOf(Injector src) {
Map<TypeLiteral<?>, DynamicItem<?>> m = new HashMap<>();
for (Map.Entry<Key<?>, Binding<?>> e : src.getBindings().entrySet()) {
TypeLiteral<?> type = e.getKey().getTypeLiteral();
if (type.getRawType() == DynamicItem.class) {
ParameterizedType p = (ParameterizedType) type.getType();
m.put(
TypeLiteral.get(p.getActualTypeArguments()[0]),
(DynamicItem<?>) e.getValue().getProvider().get());
}
}
if (m.isEmpty()) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(m);
}
public static Map<TypeLiteral<?>, DynamicSet<?>> dynamicSetsOf(Injector src) {
Map<TypeLiteral<?>, DynamicSet<?>> m = new HashMap<>();
for (Map.Entry<Key<?>, Binding<?>> e : src.getBindings().entrySet()) {
TypeLiteral<?> type = e.getKey().getTypeLiteral();
if (type.getRawType() == DynamicSet.class) {
ParameterizedType p = (ParameterizedType) type.getType();
m.put(
TypeLiteral.get(p.getActualTypeArguments()[0]),
(DynamicSet<?>) e.getValue().getProvider().get());
}
}
if (m.isEmpty()) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(m);
}
public static Map<TypeLiteral<?>, DynamicMap<?>> dynamicMapsOf(Injector src) {
Map<TypeLiteral<?>, DynamicMap<?>> m = new HashMap<>();
for (Map.Entry<Key<?>, Binding<?>> e : src.getBindings().entrySet()) {
TypeLiteral<?> type = e.getKey().getTypeLiteral();
if (type.getRawType() == DynamicMap.class) {
ParameterizedType p = (ParameterizedType) type.getType();
m.put(
TypeLiteral.get(p.getActualTypeArguments()[0]),
(DynamicMap<?>) e.getValue().getProvider().get());
}
}
if (m.isEmpty()) {
return Collections.emptyMap();
}
return Collections.unmodifiableMap(m);
}
public static List<RegistrationHandle> attachItems(
Injector src, Map<TypeLiteral<?>, DynamicItem<?>> items, String pluginName) {
if (src == null || items == null || items.isEmpty()) {
return Collections.emptyList();
}
List<RegistrationHandle> handles = new ArrayList<>(4);
try {
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();
for (Binding<Object> b : bindings(src, type)) {
handles.add(item.set(b.getKey(), b.getProvider(), pluginName));
}
}
} catch (RuntimeException | Error e) {
remove(handles);
throw e;
}
return handles;
}
public static List<RegistrationHandle> attachSets(
Injector src, Map<TypeLiteral<?>, DynamicSet<?>> sets) {
if (src == null || sets == null || sets.isEmpty()) {
return Collections.emptyList();
}
List<RegistrationHandle> handles = new ArrayList<>(4);
try {
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();
for (Binding<Object> b : bindings(src, type)) {
if (b.getKey().getAnnotation() != null) {
handles.add(set.add(b.getKey(), b.getProvider()));
}
}
}
} catch (RuntimeException | Error e) {
remove(handles);
throw e;
}
return handles;
}
public static List<RegistrationHandle> attachMaps(
Injector src, String groupName, Map<TypeLiteral<?>, DynamicMap<?>> maps) {
if (src == null || maps == null || maps.isEmpty()) {
return Collections.emptyList();
}
List<RegistrationHandle> handles = new ArrayList<>(4);
try {
for (Map.Entry<TypeLiteral<?>, DynamicMap<?>> e : maps.entrySet()) {
@SuppressWarnings("unchecked")
TypeLiteral<Object> type = (TypeLiteral<Object>) e.getKey();
@SuppressWarnings("unchecked")
PrivateInternals_DynamicMapImpl<Object> set =
(PrivateInternals_DynamicMapImpl<Object>) e.getValue();
for (Binding<Object> b : bindings(src, type)) {
if (b.getKey().getAnnotation() != null) {
handles.add(set.put(groupName, b.getKey(), b.getProvider()));
}
}
}
} catch (RuntimeException | Error e) {
remove(handles);
throw e;
}
return handles;
}
public static LifecycleListener registerInParentInjectors() {
return new LifecycleListener() {
private List<RegistrationHandle> handles;
@Inject private Injector self;
@Override
public void start() {
handles = new ArrayList<>(4);
Injector parent = self.getParent();
while (parent != null) {
handles.addAll(attachSets(self, dynamicSetsOf(parent)));
handles.addAll(attachMaps(self, "gerrit", dynamicMapsOf(parent)));
parent = parent.getParent();
}
if (handles.isEmpty()) {
handles = null;
}
}
@Override
public void stop() {
remove(handles);
handles = null;
}
};
}
private static void remove(List<RegistrationHandle> handles) {
if (handles != null) {
for (RegistrationHandle handle : handles) {
handle.remove();
}
}
}
private static <T> List<Binding<T>> bindings(Injector src, TypeLiteral<T> type) {
return src.findBindingsByType(type);
}
}