package org.opendaylight.genius.simple;
import com.google.inject.AbstractModule;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.alivenessmonitor.rev160411.AlivenessMonitorService;
public class AlivenessMonitorWiring extends AbstractModule {
- private final ClassPathScanner scanner;
+ private final GuiceClassPathBinder classPathBinder;
- public AlivenessMonitorWiring(ClassPathScanner scanner) {
- this.scanner = scanner;
+ public AlivenessMonitorWiring(GuiceClassPathBinder classPathBinder) {
+ this.classPathBinder = classPathBinder;
}
@Override
protected void configure() {
- scanner.bind(binder(), AlivenessMonitorService.class);
+ classPathBinder.bind(binder(), AlivenessMonitorService.class);
}
}
*/
package org.opendaylight.genius.simple;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
import org.opendaylight.infrautils.simple.ShellMain;
public final class GeniusMain {
private GeniusMain() { }
public static void main(String[] args) {
- ClassPathScanner scanner = new ClassPathScanner("org.opendaylight");
- new ShellMain(new GeniusWiring(scanner)).awaitShutdown();
+ GuiceClassPathBinder classPathBinder = new GuiceClassPathBinder("org.opendaylight");
+ new ShellMain(new GeniusWiring(classPathBinder)).awaitShutdown();
}
}
import com.google.inject.AbstractModule;
import org.opendaylight.daexim.DataImportBootReady;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
import org.opendaylight.infrautils.inject.guice.testutils.AnnotationsModule;
import org.opendaylight.infrautils.simple.InfraUtilsWiring;
import org.opendaylight.mdsal.simple.MdsalWiring;
public class GeniusWiring extends AbstractModule {
- private final ClassPathScanner scanner;
+ private final GuiceClassPathBinder classPathBinder;
- public GeniusWiring(ClassPathScanner scanner) {
- this.scanner = scanner;
+ public GeniusWiring(GuiceClassPathBinder classPathBinder) {
+ this.classPathBinder = classPathBinder;
}
@Override
install(new MdsalUtilWiring());
install(new LockManagerWiring());
install(new IdManagerWiring());
- install(new AlivenessMonitorWiring(scanner));
+ install(new AlivenessMonitorWiring(classPathBinder));
install(new InterfaceManagerWiring());
install(new ItmWiring());
install(new DatastoreUtilsWiring());
*/
package org.opendaylight.infrautils.inject;
-import com.google.inject.Binder;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.ClassInfo;
import io.github.classgraph.ScanResult;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.function.BiConsumer;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.Logger;
/**
* Binds the given interfaces in the given binder, using implementations discovered by scanning the class path.
*
- * @param binder The binder.
+ * @param binder The binder (modeled as a generic consumer).
* @param interfaces The requested interfaces.
*/
- public void bind(Binder binder, Class... interfaces) {
+ public <T> void bind(BiConsumer<Class<T>, Class<? extends T>> binder, Class... interfaces) {
for (Class requestedInterface : interfaces) {
bindImplementationFor(binder, requestedInterface);
}
}
@SuppressWarnings("unchecked")
- private void bindImplementationFor(Binder binder, Class requestedInterface) {
+ private <T> void bindImplementationFor(BiConsumer<Class<T>, Class<? extends T>> binder, Class requestedInterface) {
Class implementation = implementations.get(requestedInterface.getName());
if (implementation != null) {
- binder.bind(requestedInterface).to(implementation);
+ binder.accept(requestedInterface, implementation);
for (Constructor constructor : implementation.getDeclaredConstructors()) {
Annotation injectAnnotation = constructor.getAnnotation(Inject.class);
if (injectAnnotation != null) {
--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject.guice;
+
+import com.google.inject.Binder;
+import org.opendaylight.infrautils.inject.ClassPathScanner;
+
+/**
+ * Binds interfaces to implementations in Guice by scanning the classpath.
+ */
+public class GuiceClassPathBinder {
+ private final ClassPathScanner scanner;
+
+ public GuiceClassPathBinder(String prefix) {
+ this.scanner = new ClassPathScanner(prefix);
+ }
+
+ /**
+ * Binds the implementation of the given interface, if any, in the given binder, along with all dependencies.
+ *
+ * @param binder The binder to set up.
+ * @param requestedInterface The requested interface.
+ */
+ public void bind(Binder binder, Class<?> requestedInterface) {
+ scanner.bind((contract, implementation) -> binder.bind(contract).to(implementation), requestedInterface);
+ }
+}
*/
package org.opendaylight.netvirt.simple;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
import org.opendaylight.infrautils.simple.Main;
public final class NetvirtMain {
private NetvirtMain() { }
public static void main(String[] args) {
- ClassPathScanner scanner = new ClassPathScanner("org.opendaylight");
- new Main(new NetvirtWiring(scanner)).awaitShutdown();
+ GuiceClassPathBinder classPathBinder = new GuiceClassPathBinder("org.opendaylight");
+ new Main(new NetvirtWiring(classPathBinder)).awaitShutdown();
}
}
import com.google.inject.AbstractModule;
import org.opendaylight.genius.simple.GeniusWiring;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
public class NetvirtWiring extends AbstractModule {
- private final ClassPathScanner scanner;
+ private final GuiceClassPathBinder classPathBinder;
- public NetvirtWiring(ClassPathScanner scanner) {
- this.scanner = scanner;
+ public NetvirtWiring(GuiceClassPathBinder classPathBinder) {
+ this.classPathBinder = classPathBinder;
}
@Override
protected void configure() {
- install(new GeniusWiring(scanner));
+ install(new GeniusWiring(classPathBinder));
install(new AclServiceWiring());
}
import org.opendaylight.genius.interfacemanager.interfaces.InterfaceManagerService;
import org.opendaylight.genius.itm.api.IITMProvider;
import org.opendaylight.genius.simple.GeniusWiring;
-import org.opendaylight.infrautils.inject.ClassPathScanner;
+import org.opendaylight.infrautils.inject.guice.GuiceClassPathBinder;
import org.opendaylight.infrautils.inject.guice.testutils.GuiceRule2;
import org.opendaylight.infrautils.simple.ShellTestWiring;
import org.opendaylight.infrautils.simple.testutils.AbstractSimpleDistributionTest;
// TODO https://github.com/google/guice/wiki/Grapher ...
// TODO https://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/tools/jmx/Manager.html
- private static final ClassPathScanner SCANNER = new ClassPathScanner("org.opendaylight");
+ private static final GuiceClassPathBinder CLASS_PATH_BINDER = new GuiceClassPathBinder("org.opendaylight");
- public @Rule GuiceRule2 guice = new GuiceRule2(new GeniusWiring(SCANNER), new ShellTestWiring());
+ public @Rule GuiceRule2 guice = new GuiceRule2(new GeniusWiring(CLASS_PATH_BINDER), new ShellTestWiring());
@SuppressWarnings("unused")
private @Inject InterfaceManagerService interfaceManagerService;
package org.opendaylight.infrautils.inject.tests;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.mock;
-import com.google.inject.Binder;
-import com.google.inject.binder.AnnotatedBindingBuilder;
-import com.google.inject.binder.ScopedBindingBuilder;
import java.util.HashMap;
import java.util.Map;
-import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mockito;
import org.opendaylight.infrautils.inject.ClassPathScanner;
public class ClassPathScannerTest {
- private final TestBinder testBinder = mock(TestBinder.class, Mockito.CALLS_REAL_METHODS);
+ private final Map<Class<?>, Class<?>> bindings = new HashMap<>();
@Before
public void setup() {
- new ClassPathScanner("org.opendaylight.infrautils.inject.tests").bind(testBinder,
+ new ClassPathScanner("org.opendaylight.infrautils.inject.tests").bind(bindings::put,
ClassPathScannerTestTopInterface.class);
}
@Test
public void verifyImplementationBinding() {
- assertEquals(ClassPathScannerTestImplementation.class,
- testBinder.getImplementation(ClassPathScannerTestTopInterface.class));
- }
-
- private abstract static class TestBinder implements Binder {
- private Map<Class<?>, Class<?>> bindings;
-
- private <T> void storeBinding(Class<T> type, Class<? extends T> implementation) {
- if (bindings == null) {
- bindings = new HashMap<>();
- }
- bindings.put(type, implementation);
- }
-
- <T> Class<? extends T> getImplementation(Class<T> type) {
- return (Class<? extends T>) bindings.get(type);
- }
-
- @Override
- public <T> AnnotatedBindingBuilder<T> bind(Class<T> type) {
- TestAnnotatedBindingBuilder builder = mock(TestAnnotatedBindingBuilder.class, CALLS_REAL_METHODS);
- builder.setType(type);
- builder.setBinder(this);
- return builder;
- }
-
- private abstract static class TestAnnotatedBindingBuilder<T> implements AnnotatedBindingBuilder<T> {
- private Class<T> type;
- private TestBinder binder;
-
- @Nullable
- @Override
- public ScopedBindingBuilder to(Class<? extends T> implementation) {
- binder.storeBinding(type, implementation);
- return null;
- }
-
- void setType(Class<T> type) {
- this.type = type;
- }
-
- void setBinder(TestBinder binder) {
- this.binder = binder;
- }
- }
+ assertEquals(ClassPathScannerTestImplementation.class, bindings.get(ClassPathScannerTestTopInterface.class));
}
}