Merge "Add Mycilla code to odlguice"
authorTejas Nevrekar <tejas.nevrekar@gmail.com>
Thu, 23 Jul 2020 15:35:35 +0000 (15:35 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 23 Jul 2020 15:35:35 +0000 (15:35 +0000)
53 files changed:
.gitignore [new file with mode: 0644]
common/parent/pom.xml
inject/inject-guice-extensions/closeable/pom.xml [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableInjector.java [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableModule.java [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/InjectorCloseListener.java [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/MycilaCloseableInjector.java [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/main/resources/META-INF/services/com.google.inject.Module [new file with mode: 0755]
inject/inject-guice-extensions/closeable/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/tests/CloseableTestTest.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/pom.xml [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/ClassToTypeLiteralMatcherAdapter.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandler.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandlerTypeListener.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProvider.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProviderSkeleton.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MBinder.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberHandler.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberInjectorTypeListener.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandler.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandlerTypeListener.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodInvoker.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MycilaGuiceException.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/Reflect.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/Perf.java [new file with mode: 0755]
inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/TypeInfoTestTest.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/pom.xml [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250KeyProvider.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250Module.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PostConstructHandler.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PreDestroyHandler.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/main/resources/META-INF/services/com.google.inject.Module [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/A.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/AImpl.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Account.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/B.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BImpl.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Bank.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BinderHelperTest.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Client.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Id.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250LifecycleTest.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250Test.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaDestroyOrderTest.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaInitDestroyBindingsTest.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Perf.java [new file with mode: 0755]
inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/PostConstructOnCyclicDependenciesTest.java [new file with mode: 0755]
inject/inject-guice-extensions/pom.xml [new file with mode: 0644]
inject/inject-guice-testutils/pom.xml
inject/inject-guice-testutils/src/main/java/org/opendaylight/infrautils/inject/guice/testutils/AnnotationsModule.java
inject/inject-guice-testutils/src/main/java/org/opendaylight/infrautils/inject/guice/testutils/GuiceRule.java
inject/inject-guice-testutils/src/test/java/org/opendaylight/infrautils/inject/guice/testutils/tests/ExamplePureGuiceTest.java
inject/inject-guice/pom.xml
inject/pom.xml

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..db517a7
--- /dev/null
@@ -0,0 +1,6 @@
+*.project
+*.settings
+*.classpath
+*.checkstyle
+**/target
+**/target-ide
index 29222be9ba78ac9aa0182e4f8affff2b4544b143..f3437994211deb66c189be3a0d6eb02412f4a052 100644 (file)
         <artifactId>classgraph</artifactId>
         <version>4.8.47</version>
       </dependency>
-      <dependency>
-        <groupId>com.mycila.guice.extensions</groupId>
-        <artifactId>mycila-guice-jsr250</artifactId>
-        <version>4.0.rc1</version>
-      </dependency>
       <dependency>
         <groupId>com.google.inject</groupId>
         <artifactId>guice</artifactId>
diff --git a/inject/inject-guice-extensions/closeable/pom.xml b/inject/inject-guice-extensions/closeable/pom.xml
new file mode 100755 (executable)
index 0000000..794eecc
--- /dev/null
@@ -0,0 +1,79 @@
+<!--
+
+    Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlguice</groupId>
+        <artifactId>parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../../../common/parent</relativePath>
+    </parent>
+
+    <artifactId>inject.guice.extensions.closeable</artifactId>
+    <name>ODL :: odlguice :: ${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <properties>
+        <osgi.export>!org.opendaylight.odlguice.inject.guice.extensions.internal*,org.opendaylight.odlguice.inject.guice.extensions.closeable*;version="${project.version}";-noimport:=true</osgi.export>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>check-license</id>
+            <configuration>
+              <excludes>
+                <!-- Skip Apache Licensed files -->
+                org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableInjector.java,
+                org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableModule.java,
+                org/opendaylight/odlguice/inject/guice/extensions/closeable/InjectorCloseListener.java,
+                org/opendaylight/odlguice/inject/guice/extensions/closeable/MycilaCloseableInjector.java,
+                org/opendaylight/odlguice/inject/guice/extensions/closeable/tests/CloseableTestTest.java
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableInjector.java b/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableInjector.java
new file mode 100755 (executable)
index 0000000..7ab305d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.closeable;
+
+import com.google.inject.Injector;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+public interface CloseableInjector extends Injector {
+    void close();
+}
diff --git a/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableModule.java b/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/CloseableModule.java
new file mode 100755 (executable)
index 0000000..77f3cfb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.closeable;
+
+import com.google.inject.AbstractModule;
+import javax.inject.Singleton;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+public class CloseableModule extends AbstractModule {
+    public CloseableModule() {
+        super();
+    }
+
+    @Override
+    protected void configure() {
+        bind(CloseableInjector.class).to(MycilaCloseableInjector.class).in(Singleton.class);
+    }
+}
diff --git a/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/InjectorCloseListener.java b/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/InjectorCloseListener.java
new file mode 100755 (executable)
index 0000000..04fd1cf
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.closeable;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+public interface InjectorCloseListener {
+    void onInjectorClosing();
+}
\ No newline at end of file
diff --git a/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/MycilaCloseableInjector.java b/inject/inject-guice-extensions/closeable/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/MycilaCloseableInjector.java
new file mode 100755 (executable)
index 0000000..25625fe
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.closeable;
+
+import com.google.inject.Binding;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Module;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import com.google.inject.Scopes;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.Element;
+import com.google.inject.spi.InjectionPoint;
+import com.google.inject.spi.TypeConverterBinding;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+final class MycilaCloseableInjector implements CloseableInjector {
+
+    private volatile boolean closed;
+
+    @Inject
+    private volatile Injector injector;
+
+    @Override
+    public synchronized void close() {
+        if (!closed && injector != null) {
+            closed = true;
+            Injector current = injector;
+            injector = null;
+            for (Binding<?> binding : current.getAllBindings().values()) {
+                if (Scopes.isSingleton(binding)) {
+                    Object obj = binding.getProvider().get();
+                    if (obj instanceof InjectorCloseListener) {
+                        ((InjectorCloseListener) obj).onInjectorClosing();
+                    }
+                }
+            }
+        }
+    }
+
+    private Injector injector() {
+        if (closed || injector == null) {
+            throw new IllegalStateException("Injector closed !");
+        }
+        return injector;
+    }
+
+    @Override
+    public void injectMembers(Object instance) {
+        injector().injectMembers(instance);
+    }
+
+    @Override
+    public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) {
+        return injector().getMembersInjector(typeLiteral);
+    }
+
+    @Override
+    public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
+        return injector().getMembersInjector(type);
+    }
+
+    @Override
+    public Map<Key<?>, Binding<?>> getBindings() {
+        return injector().getBindings();
+    }
+
+    @Override
+    public Map<Key<?>, Binding<?>> getAllBindings() {
+        return injector().getAllBindings();
+    }
+
+    @Override
+    public <T> Binding<T> getBinding(Key<T> key) {
+        return injector().getBinding(key);
+    }
+
+    @Override
+    public <T> Binding<T> getBinding(Class<T> type) {
+        return injector().getBinding(type);
+    }
+
+    @Override
+    public <T> Binding<T> getExistingBinding(Key<T> key) {
+        return injector().getExistingBinding(key);
+    }
+
+    @Override
+    public <T> List<Binding<T>> findBindingsByType(TypeLiteral<T> type) {
+        return injector().findBindingsByType(type);
+    }
+
+    @Override
+    public <T> Provider<T> getProvider(Key<T> key) {
+        return injector().getProvider(key);
+    }
+
+    @Override
+    public <T> Provider<T> getProvider(Class<T> type) {
+        return injector().getProvider(type);
+    }
+
+    @Override
+    public <T> T getInstance(Key<T> key) {
+        return injector().getInstance(key);
+    }
+
+    @Override
+    public <T> T getInstance(Class<T> type) {
+        return injector().getInstance(type);
+    }
+
+    @Override
+    public Injector getParent() {
+        return injector().getParent();
+    }
+
+    @Override
+    public Injector createChildInjector(Iterable<? extends Module> modules) {
+        return injector().createChildInjector(modules);
+    }
+
+    @Override
+    public Injector createChildInjector(Module... modules) {
+        return injector().createChildInjector(modules);
+    }
+
+    @Override
+    public Map<Class<? extends Annotation>, Scope> getScopeBindings() {
+        return injector().getScopeBindings();
+    }
+
+    @Override
+    public Set<TypeConverterBinding> getTypeConverterBindings() {
+        return injector().getTypeConverterBindings();
+    }
+
+    @Override
+    public Map<TypeLiteral<?>, List<InjectionPoint>> getAllMembersInjectorInjectionPoints() {
+        return injector().getAllMembersInjectorInjectionPoints();
+    }
+
+    @Override
+    public List<Element> getElements() {
+        return injector().getElements();
+    }
+
+}
diff --git a/inject/inject-guice-extensions/closeable/src/main/resources/META-INF/services/com.google.inject.Module b/inject/inject-guice-extensions/closeable/src/main/resources/META-INF/services/com.google.inject.Module
new file mode 100755 (executable)
index 0000000..45a982a
--- /dev/null
@@ -0,0 +1 @@
+org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule
diff --git a/inject/inject-guice-extensions/closeable/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/tests/CloseableTestTest.java b/inject/inject-guice-extensions/closeable/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/closeable/tests/CloseableTestTest.java
new file mode 100755 (executable)
index 0000000..d03b10d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.closeable.tests;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Stage;
+import javax.inject.Singleton;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.InjectorCloseListener;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+@RunWith(JUnit4.class)
+public final class CloseableTestTest {
+
+    @Test
+    public void test() throws Exception {
+        CloseableInjector injector = Guice
+                .createInjector(Stage.PRODUCTION, new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(MustClose.class).in(Singleton.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+        Assert.assertEquals(0, MustClose.hits);
+        injector.close();
+        Assert.assertEquals(1, MustClose.hits);
+    }
+
+    static class MustClose implements InjectorCloseListener {
+        static int hits;
+
+        @Override
+        public void onInjectorClosing() {
+            hits++;
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/pom.xml b/inject/inject-guice-extensions/injection/pom.xml
new file mode 100755 (executable)
index 0000000..66926f0
--- /dev/null
@@ -0,0 +1,89 @@
+<!--
+
+    Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlguice</groupId>
+        <artifactId>parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../../../common/parent</relativePath>
+    </parent>
+
+    <artifactId>inject.guice.extensions.injection</artifactId>
+    <name>ODL :: odlguice :: ${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <properties>
+        <osgi.export>!org.opendaylight.odlguice.inject.guice.extensions.internal*,org.opendaylight.odlguice.inject.guice.extensions.injection*;version="${project.version}";-noimport:=true</osgi.export>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>check-license</id>
+            <configuration>
+              <excludes>
+                <!-- Skip Apache Licensed files -->
+                org/opendaylight/odlguice/inject/guice/extensions/injection/ClassToTypeLiteralMatcherAdapter.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandler.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandlerTypeListener.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProvider.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProviderSkeleton.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MBinder.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MemberHandler.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MemberInjectorTypeListener.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandler.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandlerTypeListener.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MethodInvoker.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/MycilaGuiceException.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/Reflect.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/tests/Perf.java,
+                org/opendaylight/odlguice/inject/guice/extensions/injection/tests/TypeInfoTestTest.java
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/ClassToTypeLiteralMatcherAdapter.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/ClassToTypeLiteralMatcherAdapter.java
new file mode 100755 (executable)
index 0000000..a09b9da
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.inject.TypeLiteral;
+import com.google.inject.matcher.AbstractMatcher;
+import com.google.inject.matcher.Matcher;
+import java.lang.reflect.AnnotatedElement;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+public class ClassToTypeLiteralMatcherAdapter extends AbstractMatcher<TypeLiteral<?>> {
+    private final Matcher<TypeLiteral<?>> matcher;
+
+    ClassToTypeLiteralMatcherAdapter(final Matcher<AnnotatedElement> classMatcher) {
+        this.matcher = new AbstractMatcher<TypeLiteral<?>>() {
+            @Override
+            public boolean matches(TypeLiteral<?> typeL) {
+                return classMatcher.matches(typeL.getRawType());
+            }
+        };
+    }
+
+    @Override
+    public boolean matches(TypeLiteral<?> typeLiteral) {
+        return matcher.matches(typeLiteral);
+    }
+
+    public static Matcher<TypeLiteral<?>> adapt(Matcher<AnnotatedElement> classMatcher) {
+        return new ClassToTypeLiteralMatcherAdapter(classMatcher);
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandler.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandler.java
new file mode 100755 (executable)
index 0000000..93471ed
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface FieldHandler<A extends Annotation> extends MemberHandler<A, Field> {
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandlerTypeListener.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/FieldHandlerTypeListener.java
new file mode 100755 (executable)
index 0000000..5b2f57a
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.InjectionListener;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class FieldHandlerTypeListener<A extends Annotation> implements TypeListener {
+    private final Class<A> annotationType;
+    private final Class<? extends FieldHandler<A>> handlerClass;
+
+    public FieldHandlerTypeListener(Class<A> annotationType, Class<? extends FieldHandler<A>> handlerClass) {
+        this.annotationType = annotationType;
+        this.handlerClass = handlerClass;
+    }
+
+    @Override
+    public <I> void hear(final TypeLiteral<I> type, TypeEncounter<I> encounter) {
+        final Provider<? extends FieldHandler<A>> provider = encounter.getProvider(handlerClass);
+        final List<Field> fields = Lists
+                .newLinkedList(Reflect.findAllAnnotatedFields(type.getRawType(), annotationType));
+        if (!fields.isEmpty()) {
+            encounter.register(new InjectionListener<I>() {
+                @Override
+                public void afterInjection(I injectee) {
+                    FieldHandler<A> handler = provider.get();
+                    for (Field field : fields) {
+                        handler.handle(type, injectee, field, field.getAnnotation(annotationType));
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProvider.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProvider.java
new file mode 100755 (executable)
index 0000000..3aaa36e
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface KeyProvider<A extends Annotation> {
+    Key<?> getKey(TypeLiteral<?> injectedType, Field injectedMember, A resourceAnnotation);
+
+    List<Key<?>> getParameterKeys(TypeLiteral<?> injectedType, Method injectedMember, A resourceAnnotation);
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProviderSkeleton.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/KeyProviderSkeleton.java
new file mode 100755 (executable)
index 0000000..c4869fe
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Annotations;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public abstract class KeyProviderSkeleton<A extends Annotation> implements KeyProvider<A> {
+
+    @Override
+    public Key<?> getKey(TypeLiteral<?> injectedType, Field injectedMember, A resourceAnnotation) {
+        for (Annotation annotation : injectedMember.getAnnotations()) {
+            if (Annotations.isBindingAnnotation(annotation.annotationType())) {
+                return Key.get(injectedType.getFieldType(injectedMember), annotation);
+            }
+        }
+        return Key.get(injectedType.getFieldType(injectedMember));
+    }
+
+    @Override
+    public List<Key<?>> getParameterKeys(TypeLiteral<?> injectedType, Method injectedMember, A resourceAnnotation) {
+        return Reflect.getParameterKeys(injectedType, injectedMember);
+    }
+
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MBinder.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MBinder.java
new file mode 100755 (executable)
index 0000000..4cae1be
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.inject.Binder;
+import com.google.inject.Binding;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Module;
+import com.google.inject.PrivateBinder;
+import com.google.inject.Provider;
+import com.google.inject.Scope;
+import com.google.inject.Stage;
+import com.google.inject.TypeLiteral;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+import com.google.inject.binder.AnnotatedConstantBindingBuilder;
+import com.google.inject.binder.LinkedBindingBuilder;
+import com.google.inject.matcher.Matcher;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.Message;
+import com.google.inject.spi.ModuleAnnotatedMethodScanner;
+import com.google.inject.spi.ProvisionListener;
+import com.google.inject.spi.TypeConverter;
+import com.google.inject.spi.TypeListener;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import org.aopalliance.intercept.MethodInterceptor;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-20
+ */
+@SuppressWarnings("checkstyle:OverloadMethodsDeclarationOrder")
+public final class MBinder implements Binder {
+
+    private final Binder binder;
+
+    private MBinder(Binder binder) {
+        this.binder = binder;
+    }
+
+    public <A extends Annotation> MBinder bindAnnotationInjector(Class<A> annotationType,
+            Class<? extends KeyProvider<A>> providerClass) {
+        binder.bindListener(Matchers.any(),
+                willInject(new MemberInjectorTypeListener<A>(annotationType, providerClass)));
+        return this;
+    }
+
+    public <A extends Annotation> MBinder handleMethodAfterInjection(Class<A> annotationType,
+            Class<? extends MethodHandler<A>> providerClass) {
+        binder.bindListener(Matchers.any(),
+                willInject(new MethodHandlerTypeListener<A>(annotationType, providerClass)));
+        return this;
+    }
+
+    public <A extends Annotation> MBinder handleFieldAfterInjection(Class<A> annotationType,
+            Class<? extends FieldHandler<A>> providerClass) {
+        binder.bindListener(Matchers.any(), willInject(new FieldHandlerTypeListener<A>(annotationType, providerClass)));
+        return this;
+    }
+
+    public <T> T willInject(T object) {
+        binder.requestInjection(object);
+        return object;
+    }
+
+    public static MBinder wrap(Binder binder) {
+        return new MBinder(binder);
+    }
+
+    // DELEGATES
+
+    @Override
+    public void addError(Message message) {
+        binder.addError(message);
+    }
+
+    @Override
+    public void addError(String message, Object... arguments) {
+        binder.addError(message, arguments);
+    }
+
+    @Override
+    public void addError(Throwable throwable) {
+        binder.addError(throwable);
+    }
+
+    @Override
+    public <T> LinkedBindingBuilder<T> bind(Key<T> key) {
+        return binder.bind(key);
+    }
+
+    @Override
+    public <T> AnnotatedBindingBuilder<T> bind(Class<T> type) {
+        return binder.bind(type);
+    }
+
+    @Override
+    public <T> AnnotatedBindingBuilder<T> bind(TypeLiteral<T> typeLiteral) {
+        return binder.bind(typeLiteral);
+    }
+
+    @Override
+    public AnnotatedConstantBindingBuilder bindConstant() {
+        return binder.bindConstant();
+    }
+
+    @Override
+    public void bindInterceptor(Matcher<? super Class<?>> classMatcher, Matcher<? super Method> methodMatcher,
+            MethodInterceptor... interceptors) {
+        for (MethodInterceptor interceptor : interceptors) {
+            requestInjection(interceptor);
+        }
+        binder.bindInterceptor(classMatcher, methodMatcher, interceptors);
+    }
+
+    @Override
+    public void bindListener(Matcher<? super TypeLiteral<?>> typeMatcher, TypeListener listener) {
+        binder.bindListener(typeMatcher, listener);
+    }
+
+    @Override
+    public void bindScope(Class<? extends Annotation> annotationType, Scope scope) {
+        binder.bindScope(annotationType, scope);
+    }
+
+    @Override
+    public void convertToTypes(Matcher<? super TypeLiteral<?>> typeMatcher, TypeConverter converter) {
+        binder.convertToTypes(typeMatcher, converter);
+    }
+
+    @Override
+    public Stage currentStage() {
+        return binder.currentStage();
+    }
+
+    @Override
+    public void disableCircularProxies() {
+        binder.disableCircularProxies();
+    }
+
+    @Override
+    public <T> MembersInjector<T> getMembersInjector(Class<T> type) {
+        return binder.getMembersInjector(type);
+    }
+
+    @Override
+    public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) {
+        return binder.getMembersInjector(typeLiteral);
+    }
+
+    @Override
+    public <T> Provider<T> getProvider(Key<T> key) {
+        return binder.getProvider(key);
+    }
+
+    @Override
+    public <T> Provider<T> getProvider(Class<T> type) {
+        return binder.getProvider(type);
+    }
+
+    @Override
+    public void install(Module module) {
+        binder.install(module);
+    }
+
+    @Override
+    public PrivateBinder newPrivateBinder() {
+        return binder.newPrivateBinder();
+    }
+
+    @Override
+    public void requestInjection(Object instance) {
+        binder.requestInjection(instance);
+    }
+
+    @Override
+    public <T> void requestInjection(TypeLiteral<T> type, T instance) {
+        binder.requestInjection(type, instance);
+    }
+
+    @Override
+    public void requestStaticInjection(Class<?>... types) {
+        binder.requestStaticInjection(types);
+    }
+
+    @Override
+    public void requireExplicitBindings() {
+        binder.requireExplicitBindings();
+    }
+
+    @Override
+    public Binder skipSources(Class... classesToSkip) {
+        return binder.skipSources(classesToSkip);
+    }
+
+    @Override
+    public Binder withSource(Object source) {
+        return binder.withSource(source);
+    }
+
+    @Override
+    public void bindListener(Matcher<? super Binding<?>> bindingMatcher, ProvisionListener... listeners) {
+        binder.bindListener(bindingMatcher, listeners);
+    }
+
+    @Override
+    public void requireAtInjectOnConstructors() {
+        binder.requireAtInjectOnConstructors();
+    }
+
+    @Override
+    public void requireExactBindingAnnotations() {
+        binder.requireExactBindingAnnotations();
+    }
+
+    @Override
+    public <T> Provider<T> getProvider(Dependency<T> dpndnc) {
+        return binder.getProvider(dpndnc);
+    }
+
+    @Override
+    public void scanModulesForAnnotatedMethods(ModuleAnnotatedMethodScanner mams) {
+        binder.scanModulesForAnnotatedMethods(mams);
+    }
+
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberHandler.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberHandler.java
new file mode 100755 (executable)
index 0000000..070c294
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.inject.TypeLiteral;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Member;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface MemberHandler<A extends Annotation, M extends Member & AnnotatedElement> {
+    void handle(TypeLiteral<?> type, Object instance, M member, A annotation);
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberInjectorTypeListener.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MemberInjectorTypeListener.java
new file mode 100755 (executable)
index 0000000..0d54192
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.common.collect.Lists;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class MemberInjectorTypeListener<A extends Annotation> implements TypeListener {
+
+    private final Class<A> annotationType;
+    private final Class<? extends KeyProvider<A>> providerClass;
+
+    public MemberInjectorTypeListener(Class<A> annotationType, Class<? extends KeyProvider<A>> providerClass) {
+        this.annotationType = annotationType;
+        this.providerClass = providerClass;
+    }
+
+    @SuppressWarnings("checkstyle:illegalCatch")
+    @Override
+    public <I> void hear(final TypeLiteral<I> injectableType, TypeEncounter<I> encounter) {
+        final Provider<? extends KeyProvider<A>> provider = encounter.getProvider(providerClass);
+        final Provider<Injector> injectorProvider = encounter.getProvider(Injector.class);
+        final List<Field> fields = Lists
+                .newLinkedList(Reflect.findAllAnnotatedFields(injectableType.getRawType(), annotationType));
+        final List<MethodInvoker> methods = Lists
+                .newLinkedList(Reflect.findAllAnnotatedInvokables(injectableType.getRawType(), annotationType));
+        if (!fields.isEmpty() || !methods.isEmpty()) {
+            encounter.register(new MembersInjector<I>() {
+                @SuppressWarnings("unchecked")
+                @Override
+                public void injectMembers(I injectee) {
+                    KeyProvider<A> keyProvider = provider.get();
+                    // inject fields
+                    for (Field field : fields) {
+                        Object value = injectorProvider.get()
+                                .getProvider(
+                                        keyProvider.getKey(injectableType, field, field.getAnnotation(annotationType)))
+                                .get();
+                        if (!field.isAccessible()) {
+//                            field.setAccessible(true);
+                            AccessController.doPrivileged((PrivilegedAction) () -> {
+                                field.setAccessible(true);
+                                return null;
+                            });
+                        }
+                        try {
+                            field.set(injectee, value);
+                        } catch (IllegalAccessException e) {
+                            throw new IllegalStateException(
+                                    "Failed to inject field " + field + ". Reason: " + e.getMessage(), e);
+                        }
+                    }
+                    // inject methods
+                    for (MethodInvoker invokable : methods) {
+                        List<Key<?>> parameterKeys = keyProvider.getParameterKeys(injectableType, invokable.method,
+                                invokable.getAnnotation(annotationType));
+                        Object[] parameters = new Object[parameterKeys.size()];
+                        for (int i = 0; i < parameters.length; i++) {
+                            parameters[i] = injectorProvider.get().getProvider(parameterKeys.get(i)).get();
+                        }
+                        try {
+                            invokable.invoke(injectee, parameters);
+                        } catch (Exception ex) {
+                            throw MycilaGuiceException.toRuntime(ex);
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandler.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandler.java
new file mode 100755 (executable)
index 0000000..a237e25
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface MethodHandler<A extends Annotation> extends MemberHandler<A, Method> {
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandlerTypeListener.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodHandlerTypeListener.java
new file mode 100755 (executable)
index 0000000..af4f26c
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import static com.google.common.collect.Lists.newLinkedList;
+import static com.google.common.collect.Lists.reverse;
+
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.InjectionListener;
+import com.google.inject.spi.TypeEncounter;
+import com.google.inject.spi.TypeListener;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class MethodHandlerTypeListener<A extends Annotation> implements TypeListener {
+    private final Class<A> annotationType;
+    private final Class<? extends MethodHandler<A>> handlerClass;
+
+    public MethodHandlerTypeListener(Class<A> annotationType, Class<? extends MethodHandler<A>> handlerClass) {
+        this.annotationType = annotationType;
+        this.handlerClass = handlerClass;
+    }
+
+    @Override
+    public <I> void hear(final TypeLiteral<I> type, TypeEncounter<I> encounter) {
+        final Provider<? extends MethodHandler<A>> provider = encounter.getProvider(handlerClass);
+        final List<Method> methods = reverse(
+                newLinkedList(Reflect.findAllAnnotatedMethods(type.getRawType(), annotationType)));
+        if (!methods.isEmpty()) {
+            encounter.register(new InjectionListener<I>() {
+                @Override
+                public void afterInjection(I injectee) {
+                    MethodHandler<A> handler = provider.get();
+                    for (Method method : methods) {
+                        handler.handle(type, injectee, method, method.getAnnotation(annotationType));
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodInvoker.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MethodInvoker.java
new file mode 100755 (executable)
index 0000000..e996998
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.inject.internal.BytecodeGen;
+import com.google.inject.internal.cglib.core.$CodeGenerationException;
+import com.google.inject.internal.cglib.reflect.$FastMethod;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@SuppressWarnings("checkstyle:finalClass")
+public class MethodInvoker implements Member, AnnotatedElement {
+
+    private static final LoadingCache<Method, MethodInvoker> INVOKERS = CacheBuilder.newBuilder().weakKeys()
+            .build(new CacheLoader<Method, MethodInvoker>() {
+                @SuppressWarnings("unchecked")
+                @Override
+                public MethodInvoker load(final Method method) throws Exception {
+                    int modifiers = method.getModifiers();
+                    if (!Modifier.isPrivate(modifiers) && !Modifier.isProtected(modifiers)) {
+                        try {
+                            final $FastMethod fastMethod = BytecodeGen
+                                    .newFastClassForMember(method.getDeclaringClass(), method).getMethod(method);
+                            return new MethodInvoker(method) {
+                                @Override
+                                public Object invoke(Object target, Object... parameters) {
+                                    try {
+                                        return fastMethod.invoke(target, parameters);
+                                    } catch (InvocationTargetException e) {
+                                        throw MycilaGuiceException.toRuntime(e);
+                                    }
+                                }
+                            };
+                        } catch ($CodeGenerationException e) {
+                            /* fall-through */
+                        }
+                    }
+                    if (!Modifier.isPublic(modifiers)
+                            || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
+//                        method.setAccessible(true);
+                        AccessController.doPrivileged((PrivilegedAction) () -> {
+                            method.setAccessible(true);
+                            return null;
+                        });
+                    }
+                    return new MethodInvoker(method);
+                }
+            });
+
+    public final Method method;
+
+    private MethodInvoker(Method method) {
+        this.method = method;
+    }
+
+    public Object invoke(Object target, Object... parameters) {
+        try {
+            return method.invoke(target, parameters);
+        } catch (IllegalAccessException e) {
+            throw MycilaGuiceException.toRuntime(e);
+        } catch (InvocationTargetException e) {
+            throw MycilaGuiceException.toRuntime(e);
+        }
+    }
+
+    public static MethodInvoker on(Method method) {
+        try {
+            return INVOKERS.get(method);
+        } catch (ExecutionException e) {
+            throw MycilaGuiceException.toRuntime(e);
+        }
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return Reflect.isAnnotationPresent(method, annotationClass);
+    }
+
+    @Override
+    public Annotation[] getAnnotations() {
+        return method.getAnnotations();
+    }
+
+    @Override
+    public int getModifiers() {
+        return method.getModifiers();
+    }
+
+    @Override
+    public String getName() {
+        return method.getName();
+    }
+
+    @Override
+    public Class<?> getDeclaringClass() {
+        return method.getDeclaringClass();
+    }
+
+    @Override
+    public Annotation[] getDeclaredAnnotations() {
+        return method.getDeclaredAnnotations();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
+        return method.getAnnotation(annotationClass);
+    }
+
+    @Override
+    public boolean isSynthetic() {
+        return method.isSynthetic();
+    }
+
+    @Override
+    public String toString() {
+        return method.toString();
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MycilaGuiceException.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/MycilaGuiceException.java
new file mode 100755 (executable)
index 0000000..2ef1e14
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class MycilaGuiceException extends RuntimeException {
+
+    public MycilaGuiceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MycilaGuiceException(Throwable cause) {
+        super(cause.getMessage(), cause);
+        setStackTrace(cause.getStackTrace());
+    }
+
+    public static RuntimeException toRuntime(Throwable throwable) {
+        while (throwable instanceof InvocationTargetException || throwable instanceof ExecutionException
+                || throwable instanceof MycilaGuiceException) {
+            throwable = throwable instanceof InvocationTargetException
+                    ? ((InvocationTargetException) throwable).getTargetException()
+                    : throwable.getCause();
+        }
+        if (throwable instanceof Error) {
+            throw (Error) throwable;
+        }
+        if (throwable instanceof RuntimeException) {
+            return (RuntimeException) throwable;
+        }
+        return new MycilaGuiceException(throwable);
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/Reflect.java b/inject/inject-guice-extensions/injection/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/injection/Reflect.java
new file mode 100755 (executable)
index 0000000..cb8a3a6
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.transform;
+import static java.util.Arrays.asList;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.internal.Annotations;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-20
+ */
+@SuppressModernizer
+public final class Reflect {
+
+    private Reflect() {
+    }
+
+    private static final Function<Signature, Method> TO_METHOD = new Function<Signature, Method>() {
+        @Override
+        public Method apply(Signature from) {
+            return from.method;
+        }
+    };
+
+    private static final List<Signature> OBJECT_METHODS = Lists
+            .newArrayList(transform(asList(Object.class.getDeclaredMethods()), new Function<Method, Signature>() {
+                @Override
+                public Signature apply(Method from) {
+                    return new Signature(from);
+                }
+            }));
+
+    private static Key<?> buildKey(TypeLiteral<?> type, Annotation[] annotations) {
+        for (Annotation annotation : annotations) {
+            if (Annotations.isBindingAnnotation(annotation.annotationType())) {
+                return Key.get(type, annotation);
+            }
+        }
+        return Key.get(type);
+    }
+
+    private static final LoadingCache<AnnotatedElement, Set<Class<? extends Annotation>>> ANNOT_CACHE = CacheBuilder
+            .newBuilder().weakKeys().softValues()
+            .build(new CacheLoader<AnnotatedElement, Set<Class<? extends Annotation>>>() {
+                @Override
+                public Set<Class<? extends Annotation>> load(AnnotatedElement ex) throws Exception {
+                    Annotation[] annotations = ex.getDeclaredAnnotations();
+                    Set<Class<? extends Annotation>> annotationTypes = new HashSet<Class<? extends Annotation>>(
+                            annotations.length);
+                    for (Annotation annotation : annotations) {
+                        annotationTypes.add(annotation.annotationType());
+                    }
+                    return annotationTypes;
+                }
+            });
+
+    private static final LoadingCache<Class<?>, List<Signature>> METHODS = CacheBuilder.newBuilder().weakKeys()
+            .softValues().build(new CacheLoader<Class<?>, List<Signature>>() {
+                @Override
+                public List<Signature> load(Class<?> clazz) throws Exception {
+                    List<Signature> sup;
+                    Class<?> sc = clazz.getSuperclass();
+                    if (sc == null) {
+                        sup = Collections.emptyList();
+                    } else if (sc == Object.class) {
+                        sup = OBJECT_METHODS;
+                    } else {
+                        sup = METHODS.get(sc);
+                    }
+                    Method[] methods = clazz.isInterface() ? clazz.getMethods() : clazz.getDeclaredMethods();
+                    final List<Signature> thisMethods = new ArrayList<Signature>(methods.length);
+                    for (Method method : methods) {
+                        if (!(method.isSynthetic() || method.isBridge())) {
+                            thisMethods.add(new Signature(method));
+                        }
+                    }
+                    return Lists.newLinkedList(concat(thisMethods, Iterables.filter(sup, new Predicate<Signature>() {
+                        @Override
+                        public boolean apply(Signature input) {
+                            int pos = thisMethods.indexOf(input);
+                            if (pos == -1) {
+                                return true;
+                            }
+                            Signature override = thisMethods.get(pos);
+                            return !overrides(override.method, input.method);
+                        }
+                    })));
+                }
+            });
+
+    public static boolean isAnnotationPresent(AnnotatedElement annotatedElement,
+            Class<? extends Annotation> annotationType) {
+        try {
+            return ANNOT_CACHE.get(annotatedElement).contains(annotationType);
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    public static List<Key<?>> getParameterKeys(TypeLiteral<?> type, Method method) {
+        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
+        List<TypeLiteral<?>> parameterTypes = type.getParameterTypes(method);
+        List<Key<?>> keys = new ArrayList<Key<?>>(parameterTypes.size());
+        for (int i = 0; i < parameterTypes.size(); i++) {
+            keys.add(buildKey(parameterTypes.get(i), parameterAnnotations[i]));
+        }
+        return keys;
+    }
+
+    public static Iterable<MethodInvoker> findAllAnnotatedInvokables(Class<?> type, Class<? extends Annotation> annot) {
+        return transform(findAllAnnotatedMethods(type, annot), new Function<Method, MethodInvoker>() {
+            @Override
+            public MethodInvoker apply(Method method) {
+                return MethodInvoker.on(method);
+            }
+        });
+    }
+
+    public static Iterable<Method> findAllAnnotatedMethods(Class<?> type, Class<? extends Annotation> annot) {
+        return Iterables.filter(findAllMethods(type), annotatedBy(annot));
+    }
+
+    public static Iterable<Method> findAllMethods(Class<?> type) {
+        try {
+            return transform(METHODS.get(type), TO_METHOD);
+        } catch (ExecutionException e) {
+            throw MycilaGuiceException.toRuntime(e);
+        }
+    }
+
+    public static Iterable<Field> findAllAnnotatedFields(Class<?> type, Class<? extends Annotation> annot) {
+        return Iterables.filter(findAllFields(type), annotatedBy(annot));
+    }
+
+    public static Iterable<Field> findAllFields(Class<?> type) {
+        return type == null || type == Object.class ? new LinkedList<Field>()
+                : concat(Lists.newArrayList(type.getDeclaredFields()), findAllFields(type.getSuperclass()));
+    }
+
+    public static Class<?> getTargetClass(Class<?> proxy) {
+        if (proxy.getName().contains("$$")) {
+            do {
+                proxy = proxy.getSuperclass();
+            } while (proxy.getName().contains("$$"));
+            return proxy;
+        }
+        return proxy;
+    }
+
+    public static Class<?> getTargetClass(Object instance) {
+        return getTargetClass(instance.getClass());
+    }
+
+    public static <T extends AnnotatedElement> Predicate<T> annotatedBy(
+            final Class<? extends Annotation> annotationType) {
+        return new Predicate<T>() {
+            @Override
+            public boolean apply(T element) {
+                return Reflect.isAnnotationPresent(element, annotationType);
+            }
+        };
+    }
+
+    public static Predicate<Method> withSignature(final String methodName, final Class<?>... classes) {
+        return new Predicate<Method>() {
+            @Override
+            public boolean apply(Method member) {
+                if (!member.getName().equals(methodName)) {
+                    return false;
+                }
+                Class<?>[] thisParams = member.getParameterTypes();
+                if (thisParams.length != classes.length) {
+                    return false;
+                }
+                int cls = 0;
+                for (Class<?> thisParam : thisParams) {
+                    if (thisParam != classes[cls++]) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        };
+    }
+
+    /**
+     * Returns true if a overrides b. Assumes signatures of a and b are the same and
+     * a's declaring class is a subclass of b's declaring class.
+     */
+    public static boolean overrides(Method methodA, Method methodB) {
+        // See JLS section 8.4.8.1
+        int modifiers = methodB.getModifiers();
+        if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) {
+            return true;
+        }
+        if (Modifier.isPrivate(modifiers)) {
+            return false;
+        }
+        // b must be package-private
+        return methodA.getDeclaringClass().getPackage().equals(methodB.getDeclaringClass().getPackage());
+    }
+
+    private static final class Signature {
+        public final Class[] parameterTypes;
+        private final int hash;
+        public final Method method;
+
+        Signature(Method method) {
+            this.method = method;
+            this.parameterTypes = method.getParameterTypes();
+            int methodHash = method.hashCode();
+            methodHash = methodHash * 31 + parameterTypes.length;
+            for (Class parameterType : parameterTypes) {
+                methodHash = methodHash * 31 + parameterType.hashCode();
+            }
+            this.hash = methodHash;
+        }
+
+        @Override
+        public int hashCode() {
+            return this.hash;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof Signature)) {
+                return false;
+            }
+            Signature other = (Signature) obj;
+            if (!method.getName().equals(other.method.getName())) {
+                return false;
+            }
+            if (parameterTypes.length != other.parameterTypes.length) {
+                return false;
+            }
+            for (int i = 0; i < parameterTypes.length; i++) {
+                if (parameterTypes[i] != other.parameterTypes[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/Perf.java b/inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/Perf.java
new file mode 100755 (executable)
index 0000000..14abe3e
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection.tests;
+
+import com.google.common.collect.Iterables;
+import java.io.File;
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.Reflect;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public final class Perf {
+    private Perf() {
+
+    }
+
+    public static void main(String[] args) throws Exception {
+        perfTestMembers();
+    }
+
+    private static void perfTestMembers() throws Exception {
+        List<Class<?>> classes = new LinkedList<Class<?>>();
+        JarFile jarFile = new JarFile(new File("C:\\Program Files\\Java\\jdk1.7.0_15\\jre\\lib\\rt.jar"));
+        Enumeration<JarEntry> enums = jarFile.entries();
+        while (enums.hasMoreElements()) {
+            JarEntry entry = enums.nextElement();
+            if (entry.getName().endsWith(".class")) {
+                if (entry.getName().startsWith("javax/swing")
+                    || entry.getName().startsWith("java/awt")
+                    || entry.getName().startsWith("java/awt")) {
+                    classes.add(Class
+                            .forName(entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6)));
+                }
+            }
+        }
+
+        // start visual VM
+        Thread.sleep(10000);
+
+        for (int i = 0; i < 100; i++) {
+            long time = System.nanoTime();
+            for (Class<?> c : classes) {
+                Iterables.size(Reflect.findAllAnnotatedMethods(c, Deprecated.class));
+            }
+            long end = System.nanoTime();
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/TypeInfoTestTest.java b/inject/inject-guice-extensions/injection/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/injection/tests/TypeInfoTestTest.java
new file mode 100755 (executable)
index 0000000..9044cab
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.injection.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.Lists;
+import java.util.Collection;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.Reflect;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-21
+ */
+@RunWith(JUnit4.class)
+public class TypeInfoTestTest {
+
+    @Test
+    public void test() throws Exception {
+        //assertEquals(15, describe(Reflect.findAllMethods(getClass())).size());
+        //assertEquals(0, describe(Reflect.findAllFields(getClass())).size());
+        assertEquals(1, describe(Reflect.findAllAnnotatedMethods(getClass(), Test.class)).size());
+        //assertEquals(1, describe(Reflect.findAllAnnotatedInvokables(getClass(), Test.class)).size());
+    }
+
+    private <T> Collection<T> describe(Collection<T> clsses) {
+        return clsses;
+    }
+
+    private <T> Collection<T> describe(Iterable<T> clss) {
+        return describe(Lists.newLinkedList(clss));
+    }
+
+    @Override
+    protected Object clone() throws CloneNotSupportedException {
+        return super.clone();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    public TypeInfoTestTest() {
+        super();
+    }
+
+    @Override
+    public String toString() {
+        return super.toString();
+    }
+}
\ No newline at end of file
diff --git a/inject/inject-guice-extensions/jsr250/pom.xml b/inject/inject-guice-extensions/jsr250/pom.xml
new file mode 100755 (executable)
index 0000000..8e11ca4
--- /dev/null
@@ -0,0 +1,100 @@
+<!--
+
+    Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlguice</groupId>
+        <artifactId>parent</artifactId>
+        <version>1.0.0-SNAPSHOT</version>
+        <relativePath>../../../common/parent</relativePath>
+    </parent>
+
+    <artifactId>inject.guice.extensions.jsr250</artifactId>
+    <name>ODL :: odlguice :: ${project.artifactId}</name>
+    <packaging>jar</packaging>
+
+    <properties>
+        <osgi.export>!org.opendaylight.odlguice.inject.guice.extensions.internal*,org.opendaylight.odlguice.inject.guice.extensions.jsr250*;version="${project.version}";-noimport:=true</osgi.export>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.inject</groupId>
+            <artifactId>guice</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+          <groupId>javax.annotation</groupId>
+          <artifactId>javax.annotation-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlguice</groupId>
+            <artifactId>inject.guice.extensions.injection</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.odlguice</groupId>
+            <artifactId>inject.guice.extensions.closeable</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>check-license</id>
+            <configuration>
+              <excludes>
+                <!-- Skip Apache Licensed files -->
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250KeyProvider.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250Module.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PostConstructHandler.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PreDestroyHandler.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Account.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/AImpl.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/A.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Bank.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BImpl.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BinderHelperTest.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/B.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Client.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Id.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250LifecycleTest.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250Test.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaDestroyOrderTest.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaInitDestroyBindingsTest.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Perf.java,
+                org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/PostConstructOnCyclicDependenciesTest.java
+              </excludes>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250KeyProvider.java b/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250KeyProvider.java
new file mode 100755 (executable)
index 0000000..1cf774e
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import java.lang.reflect.Field;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.KeyProviderSkeleton;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+class Jsr250KeyProvider extends KeyProviderSkeleton<Resource> {
+
+    @Inject Injector injector;
+
+    @Override
+    public Key<?> getKey(TypeLiteral<?> injectedType, Field injectedMember, Resource resourceAnnotation) {
+        String name = resourceAnnotation.name();
+
+        if (name.length() != 0) {
+            // explicit key
+
+            // if a name is provided, it acts as a Named binding and this means we ask for a precise key
+            return Key.get(injectedType.getFieldType(injectedMember), Names.named(name));
+
+        } else {
+            // implicit key
+
+            // if no name given, try a combination with the field name
+            Key<?> implicitKey = Key.get(injectedType.getFieldType(injectedMember),
+                    Names.named(injectedMember.getName()));
+
+            if (injector.getExistingBinding(implicitKey) != null) {
+                return implicitKey;
+
+            } else {
+                // else create the find based on the field type (default behavior) - with
+                // optional existing binding annotations
+                return super.getKey(injectedType, injectedMember, resourceAnnotation);
+            }
+
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250Module.java b/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250Module.java
new file mode 100755 (executable)
index 0000000..dd19320
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
+import com.google.inject.AbstractModule;
+import com.google.inject.Binding;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Scope;
+import com.google.inject.Scopes;
+import com.google.inject.Singleton;
+import com.google.inject.TypeLiteral;
+import com.google.inject.spi.Dependency;
+import com.google.inject.spi.HasDependencies;
+import com.google.inject.spi.ProviderInstanceBinding;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.InjectorCloseListener;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MBinder;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MethodHandler;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.Reflect;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@SuppressModernizer
+public class Jsr250Module extends AbstractModule {
+
+    @Override
+    public void configure() {
+        requireBinding(CloseableInjector.class);
+        MyJsr250Destroyer destroyer = new MyJsr250Destroyer();
+        requestInjection(destroyer);
+        bind(MyJsr250Destroyer.class).toInstance(destroyer);
+        bind(Jsr250KeyProvider.class).in(Singleton.class);
+        bind(Jsr250PostConstructHandler.class).in(Singleton.class);
+        bind(new TypeLiteral<MethodHandler<PreDestroy>>() {
+        }).to(Jsr250PreDestroyHandler.class).in(Singleton.class);
+        MBinder.wrap(binder()).bindAnnotationInjector(Resource.class, Jsr250KeyProvider.class)
+                .handleMethodAfterInjection(PostConstruct.class, Jsr250PostConstructHandler.class);
+    }
+
+    static class MyJsr250Destroyer implements InjectorCloseListener {
+        @Inject
+        Injector injector;
+
+        @Inject
+        MethodHandler<PreDestroy> destroyer;
+
+        @Override
+        public void onInjectorClosing() {
+            Map<Key<?>, Binding<?>> bindings = injector.getAllBindings();
+            Multimap<Binding<?>, Binding<?>> dependants = Multimaps.newSetMultimap(
+                    new IdentityHashMap<Binding<?>, Collection<Binding<?>>>(), new Supplier<Set<Binding<?>>>() {
+                        @Override
+                        public Set<Binding<?>> get() {
+                            return new HashSet<Binding<?>>();
+                        }
+                    });
+            for (Binding<?> binding : bindings.values()) {
+                if (binding instanceof HasDependencies) {
+                    for (Dependency<?> dependency : ((HasDependencies) binding).getDependencies()) {
+                        if (bindings.containsKey(dependency.getKey())) {
+                            dependants.put(injector.getBinding(dependency.getKey()), binding);
+                        }
+                    }
+                }
+            }
+            Map<Object, Object> done = new IdentityHashMap<Object, Object>(bindings.size());
+            for (final Binding<?> binding : bindings.values()) {
+                if (Scopes.isSingleton(binding)) {
+                    close(binding, done, dependants);
+                }
+            }
+            for (Scope scope : injector.getScopeBindings().values()) {
+                preDestroy(scope);
+            }
+        }
+
+        @SuppressFBWarnings("REC_CATCH_EXCEPTION")
+        @SuppressWarnings("illegalCatch")
+        private void close(Binding<?> binding, Map<Object, Object> done, Multimap<Binding<?>, Binding<?>> dependants) {
+            if (!done.containsKey(binding)) {
+                done.put(binding, Void.TYPE);
+                for (Binding<?> dependant : dependants.get(binding)) {
+                    close(dependant, done, dependants);
+                }
+                try {
+                    if (binding instanceof ProviderInstanceBinding<?>) {
+                        Object obj = ((ProviderInstanceBinding) binding).getProviderInstance();
+                        if (!done.containsKey(obj)) {
+                            preDestroy(obj);
+                            done.put(obj, Void.TYPE);
+                        }
+                    } else if (Scopes.isSingleton(binding)) {
+                        Object obj = binding.getProvider().get();
+                        if (!done.containsKey(obj)) {
+                            preDestroy(obj);
+                            done.put(obj, Void.TYPE);
+                        }
+                    }
+                } catch (Exception ex) {
+                    // just ignore close errors
+                }
+            }
+        }
+
+        private void preDestroy(Object instance) {
+            TypeLiteral<?> type = TypeLiteral.get(Reflect.getTargetClass(instance));
+            for (Method method : Reflect.findAllAnnotatedMethods(type.getRawType(), PreDestroy.class)) {
+                destroyer.handle(type, instance, method, method.getAnnotation(PreDestroy.class));
+            }
+        }
+    }
+
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PostConstructHandler.java b/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PostConstructHandler.java
new file mode 100755 (executable)
index 0000000..48616e3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MethodHandler;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MethodInvoker;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.Reflect;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+class Jsr250PostConstructHandler implements MethodHandler<PostConstruct> {
+
+    @Inject
+    Provider<Injector> injector;
+
+    @Override
+    public void handle(TypeLiteral<?> type, Object instance, Method method, PostConstruct annotation) {
+        if (!Modifier.isStatic(method.getModifiers())) {
+            List<Key<?>> parameterKeys = Reflect.getParameterKeys(type, method);
+            Object[] parameters = new Object[parameterKeys.size()];
+            for (int i = 0; i < parameters.length; i++) {
+                parameters[i] = injector.get().getProvider(parameterKeys.get(i)).get();
+            }
+            MethodInvoker.on(method).invoke(instance, parameters);
+        }
+    }
+
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PreDestroyHandler.java b/inject/inject-guice-extensions/jsr250/src/main/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/Jsr250PreDestroyHandler.java
new file mode 100755 (executable)
index 0000000..7dc3f44
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250;
+
+import com.google.inject.TypeLiteral;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import javax.annotation.PreDestroy;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MethodHandler;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MethodInvoker;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+class Jsr250PreDestroyHandler implements MethodHandler<PreDestroy> {
+    @Override
+    public void handle(TypeLiteral<?> type, Object instance, Method method, PreDestroy annotation) {
+        if (!Modifier.isStatic(method.getModifiers())) {
+            MethodInvoker.on(method).invoke(instance);
+        }
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/main/resources/META-INF/services/com.google.inject.Module b/inject/inject-guice-extensions/jsr250/src/main/resources/META-INF/services/com.google.inject.Module
new file mode 100755 (executable)
index 0000000..de49fb9
--- /dev/null
@@ -0,0 +1 @@
+org.opendaylight.infrautils.inject.guice.extensions.jsr250.Jsr250Module
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/A.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/A.java
new file mode 100755 (executable)
index 0000000..71e81e9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface A {
+    void callA();
+
+    boolean hasBeenCalled();
+}
\ No newline at end of file
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/AImpl.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/AImpl.java
new file mode 100755 (executable)
index 0000000..31aa95a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class AImpl implements A {
+    //@Inject
+    private Provider<B> other;
+    private boolean called = false;
+
+    @Inject
+    public AImpl(Provider<B> obj) {
+        this.other = obj;
+    }
+
+    @PostConstruct
+    public void init() {
+        other.get().callB();
+    }
+
+    @Override
+    public void callA() {
+        called = true;
+    }
+
+    public boolean hasBeenCalled() {
+        return called;
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Account.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Account.java
new file mode 100755 (executable)
index 0000000..bfbf3a3
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Provider;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class Account {
+
+    @Resource
+    Bank bank;
+
+    String number;
+
+    @Resource
+    void init(Client client, @Named("RNG") Provider<Id> rng) {
+        number = bank.id() + "" + client.id() + "" + rng.get().id();
+    }
+
+    public String getNumber() {
+        return number;
+    }
+
+    void close() {
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/B.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/B.java
new file mode 100755 (executable)
index 0000000..90581f4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public interface B {
+    void callB();
+
+    boolean hasBeenCalled();
+}
\ No newline at end of file
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BImpl.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BImpl.java
new file mode 100755 (executable)
index 0000000..0bd6fcc
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class BImpl implements B {
+    @Inject
+    private Provider<A> obj;
+
+    private boolean called = false;
+
+    @PostConstruct
+    public void init() {
+        obj.get().callA();
+    }
+
+    @Override
+    public void callB() {
+        called = true;
+    }
+
+    public boolean hasBeenCalled() {
+        return called;
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Bank.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Bank.java
new file mode 100755 (executable)
index 0000000..0f912b2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@Singleton
+public class Bank {
+
+    List<Account> accounts = new ArrayList<Account>();
+
+    @Resource
+    Provider<Account> provider;
+
+    @PostConstruct
+    void openBank() {
+        // create two account initially
+        accounts.add(provider.get());
+        accounts.add(provider.get());
+    }
+
+    @PreDestroy
+    void closeBank() {
+        accounts.clear();
+    }
+
+    int id() {
+        return 2;
+    }
+
+    List<Account> accounts() {
+        return accounts;
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BinderHelperTest.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/BinderHelperTest.java
new file mode 100755 (executable)
index 0000000..9849b7d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.KeyProviderSkeleton;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MBinder;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@RunWith(JUnit4.class)
+public class BinderHelperTest {
+
+    @Autowire
+    CloseableInjector jsr250Injector;
+
+    @Test
+    public void test() throws Exception {
+        assertNull(jsr250Injector);
+        Guice.createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+            @Override
+            protected void configure() {
+                MBinder.wrap(binder()).bindAnnotationInjector(Autowire.class, AutowireKeyProvider.class);
+                requestInjection(BinderHelperTest.this);
+            }
+        });
+        assertNotNull(jsr250Injector);
+    }
+
+    @Target({METHOD, CONSTRUCTOR, FIELD})
+    @Retention(RUNTIME)
+    static @interface Autowire {
+        String value() default "";
+    }
+
+    static class AutowireKeyProvider extends KeyProviderSkeleton<Autowire> {
+        @Override
+        public Key<?> getKey(TypeLiteral<?> injectedType, Field injectedMember, Autowire resourceAnnotation) {
+            String name = resourceAnnotation.value();
+            return name.length() == 0 ? super.getKey(injectedType, injectedMember, resourceAnnotation)
+                    : Key.get(injectedType.getFieldType(injectedMember), Names.named(name));
+        }
+    }
+
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Client.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Client.java
new file mode 100755 (executable)
index 0000000..7940e46
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class Client {
+    public int id() {
+        return 3;
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Id.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Id.java
new file mode 100755 (executable)
index 0000000..f9693c4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class Id {
+    final int id;
+
+    public Id(int id) {
+        this.id = id;
+    }
+
+    public int id() {
+        return id;
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250LifecycleTest.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250LifecycleTest.java
new file mode 100755 (executable)
index 0000000..1159f35
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Singleton;
+import org.junit.Test;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class Jsr250LifecycleTest {
+
+    public abstract static class LifecycleBase {
+        public String startSequence = "";
+        public String stopSequence = "";
+    }
+
+    @Singleton
+    public static class LifecycleSimple extends LifecycleBase {
+        @PostConstruct
+        public void init() {
+            startSequence += "A";
+        }
+
+        @PreDestroy
+        public void destroy() {
+            stopSequence += "A";
+        }
+    }
+
+    @Singleton
+    public static class LifecycleMultiple extends LifecycleBase {
+        @PostConstruct
+        public void init() {
+            startSequence += "A";
+        }
+
+        @PostConstruct
+        public void init2() {
+            startSequence += "B";
+        }
+
+        @PreDestroy
+        public void destroy() {
+            stopSequence += "A";
+        }
+
+        @PreDestroy
+        public void destroy2() {
+            stopSequence += "B";
+        }
+    }
+
+    @Singleton
+    public static class LifecycleExtends extends LifecycleSimple {
+        @PostConstruct
+        public void init2() {
+            startSequence += "X";
+        }
+
+        @PreDestroy
+        public void destroy2() {
+            stopSequence += "X";
+        }
+    }
+
+    @Singleton
+    public static class LifecycleOverrides extends LifecycleSimple {
+        @Override
+        @PostConstruct
+        public void init() {
+            startSequence += "B";
+        }
+
+        @Override
+        @PreDestroy
+        public void destroy() {
+            stopSequence += "B";
+        }
+    }
+
+    @Singleton
+    public static class LifecycleOverridesRemovesAnnotations extends LifecycleOverrides {
+        @Override
+        public void init() {
+            startSequence += "C";
+        }
+
+        @Override
+        public void destroy() {
+            stopSequence += "C";
+        }
+    }
+
+    @Singleton
+    public static class LifecyclePrivateMethods extends LifecycleBase {
+        @PostConstruct
+        private void init() {
+            startSequence += "D";
+        }
+
+        @PreDestroy
+        private void destroy() {
+            stopSequence += "D";
+        }
+    }
+
+    @Singleton
+    public static class LifecycleSameNamePrivateMethods extends LifecyclePrivateMethods {
+        @PostConstruct
+        private void init() {
+            startSequence += "E";
+        }
+
+        @PreDestroy
+        private void destroy() {
+            stopSequence += "E";
+        }
+    }
+
+    @Test
+    public void testLifecycle() {
+        assertLifeCycleSequence(LifecycleSimple.class, "A", "A");
+        assertLifeCycleSequence(LifecycleExtends.class, "AX", "XA");
+        assertLifeCycleSequence(LifecycleOverrides.class, "B", "B");
+        assertLifeCycleSequence(LifecycleOverridesRemovesAnnotations.class, "", "");
+        assertLifeCycleSequence(LifecyclePrivateMethods.class, "D", "D");
+        // TODO: verify if private methodes of super classes should be invoked before
+        // subclasses in case of @PostConstruct
+        // assertLifeCycleSequence(LifecycleSameNamePrivateMethods.class, "ED", "DE");
+        assertLifeCycleSequence(LifecycleSameNamePrivateMethods.class, "DE", "ED");
+
+        // order among methods in same class is undefined so we just test that all of them were called
+        assertLifeCycleSequenceContainsAll(LifecycleMultiple.class, "AB", "BA");
+    }
+
+    private void assertLifeCycleSequenceContainsAll(final Class<? extends LifecycleBase> clazz, String startSequence,
+            String endSequence) {
+        CloseableInjector injector = createInjector(clazz);
+        LifecycleBase component = injector.getInstance(clazz);
+        assertContainsAll(component.startSequence, startSequence);
+        injector.close();
+        assertContainsAll(component.stopSequence, endSequence);
+    }
+
+    private void assertLifeCycleSequence(final Class<? extends LifecycleBase> clazz, String expectedStartSequence,
+            String expectedStopSequence) {
+        CloseableInjector injector = createInjector(clazz);
+        LifecycleBase component = injector.getInstance(clazz);
+        assertEquals(expectedStartSequence, component.startSequence);
+        injector.close();
+        assertEquals(expectedStopSequence, component.stopSequence);
+    }
+
+    private CloseableInjector createInjector(final Class<? extends LifecycleBase> clazz) {
+        return Guice.createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+            @Override
+            protected void configure() {
+                bind(clazz);
+            }
+        }).getInstance(CloseableInjector.class);
+    }
+
+    private void assertContainsAll(String string, String requiredCharacters) {
+        for (char ch : requiredCharacters.toCharArray()) {
+            if (string.indexOf(ch) == -1) {
+                fail("String [" + string + "] does not contain character [" + ch + "]");
+            }
+        }
+    }
+}
+
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250Test.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Jsr250Test.java
new file mode 100755 (executable)
index 0000000..cbc2cc8
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.Stage;
+import com.google.inject.matcher.Matchers;
+import com.google.inject.name.Names;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.MBinder;
+import org.opendaylight.odlguice.inject.guice.extensions.injection.Reflect;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@RunWith(JUnit4.class)
+public class Jsr250Test {
+
+    @Test
+    public void test_resource_with_type() throws Exception {
+        Guice.createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule()).getInstance(Res1Class.class);
+        assertEquals(2, Res1Class.verified);
+    }
+
+    static class Res1Class {
+        static int verified;
+
+        @Resource
+        Injector injector;
+
+        @Resource
+        Provider<Injector> provider;
+
+        @Resource
+        void init(AA aa) {
+            // field injection is done before method injection
+            assertNotNull(injector);
+            assertNotNull(provider);
+            assertNotNull(aa);
+            verified++;
+        }
+
+        @PostConstruct
+        void init() {
+            assertNotNull(injector);
+            assertNotNull(provider);
+            assertSame(injector, provider.get());
+            verified++;
+        }
+    }
+
+    @Test
+    public void test_resource_with_name() throws Exception {
+        final AA aa1 = new AA();
+        final AA aa2 = new AA();
+        Res2Class res2 = Guice
+                .createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(AA.class).annotatedWith(Names.named("aa1")).toInstance(aa1);
+                        bind(AA.class).annotatedWith(Names.named("aa2")).toInstance(aa2);
+                    }
+                }).getInstance(Res2Class.class);
+        assertEquals(aa1, res2.aa1);
+        assertEquals(aa2, res2.aa2);
+        assertTrue(res2.aa1 != res2.aa2);
+    }
+
+    static class Res2Class {
+        @Resource
+        AA aa1;
+
+        @Resource
+        AA aa2;
+    }
+
+    @Test
+    public void test_post_inject_param() throws Exception {
+        assertFalse(MyM.AAA.CALLED);
+        assertFalse(MyM.AAA.SECOND);
+        Guice.createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule(), new MyM());
+        assertTrue(MyM.AAA.CALLED);
+        assertTrue(MyM.AAA.SECOND);
+    }
+
+    static class MyM extends AbstractModule {
+        @Override
+        protected void configure() {
+            bind(AAA.class);
+        }
+
+        @Singleton
+        static class AAA {
+            static boolean CALLED;
+            static boolean SECOND;
+
+            @Inject
+            BBB bbb;
+
+            @PostConstruct
+            void init() {
+                SECOND = true;
+                assertNotNull(bbb);
+            }
+
+            @PostConstruct
+            void init(BBB bb) {
+                assertNotNull(bb);
+                assertNotNull(bbb);
+                CALLED = true;
+            }
+        }
+    }
+
+    @Singleton
+    static class BBB {
+    }
+
+    @Test
+    public void test_destroy() throws Exception {
+        final Class[] cc = {AA.class};
+        CloseableInjector injector = Guice
+                .createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        for (Class<?> c : cc) {
+                            bind(c);
+                        }
+                        // just for fun
+                        MBinder.wrap(binder()).bindInterceptor(Matchers.subclassesOf(Base.class), Matchers.any(),
+                                new MethodInterceptor() {
+                                    @Override
+                                    public Object invoke(MethodInvocation invocation) throws Throwable {
+                                        return invocation.proceed();
+                                    }
+                                });
+                    }
+                }).getInstance(CloseableInjector.class);
+        for (Class<?> c : cc) {
+            injector.getInstance(c);
+            injector.getInstance(c);
+        }
+
+        Collections.sort(Base.CALLS);
+        assertEquals("[]", Base.CALLS.toString());
+
+        for (Class<?> c : cc) {
+            injector.getInstance(c);
+        }
+
+        injector.close();
+
+        Collections.sort(Base.CALLS);
+        assertEquals("[AA]", Base.CALLS.toString());
+    }
+
+    static class Base {
+        static final List<String> CALLS = new ArrayList<String>();
+
+        @PreDestroy
+        void close() {
+            CALLS.add(Reflect.getTargetClass(getClass()).getSimpleName());
+        }
+    }
+
+    @Singleton
+    static class AA extends Base {
+    }
+
+    @Test
+    public void test_inject_in_interceptor() throws Exception {
+        B.calls.clear();
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        MBinder.wrap(binder()).bindInterceptor(Matchers.subclassesOf(A.class), Matchers.any(),
+                                new MethodInterceptor() {
+                                    @Resource
+                                    Injector injector;
+
+                                    @Override
+                                    public Object invoke(MethodInvocation invocation) throws Throwable {
+                                        assertNotNull(injector);
+                                        return invocation.proceed();
+                                    }
+                                });
+                    }
+                }).getInstance(CloseableInjector.class);
+        B obj = injector.getInstance(B.class);
+        assertSame(obj, injector.getInstance(B.class));
+        obj.intercept();
+        injector.close();
+        assertEquals("[1, 2, 3]", B.calls.toString());
+    }
+
+    @Test
+    public void test() throws Exception {
+        B.calls.clear();
+        CloseableInjector injector = Guice
+                .createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                    }
+                }).getInstance(CloseableInjector.class);
+        injector.getInstance(B.class);
+        assertEquals("[1, 2]", B.calls.toString());
+        injector.close();
+        assertEquals("[1, 2, 3]", B.calls.toString());
+    }
+
+    static class A {
+        static List<Integer> calls = new LinkedList<Integer>();
+
+        @Inject
+        void method(B obj) {
+            calls.add(1);
+        }
+
+        @PostConstruct
+        void init() {
+            calls.add(2);
+        }
+
+        @PreDestroy
+        void close() {
+            calls.add(3);
+        }
+    }
+
+    @Singleton
+    static class B extends A {
+        void intercept() {
+        }
+    }
+
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaDestroyOrderTest.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaDestroyOrderTest.java
new file mode 100755 (executable)
index 0000000..79a0af4
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Stage;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.junit.Test;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class MycilaDestroyOrderTest {
+
+    @Singleton
+    public static class Repository {
+        private boolean closed = false;
+
+        @PreDestroy
+        public void close() {
+            closed = true;
+        }
+
+        public void writeApplicationStatus(String message) {
+            if (closed) {
+                throw new IllegalStateException("Repository closed!");
+            }
+        }
+    }
+
+    @Singleton
+    public static class Service {
+        @Inject
+        private Repository repository;
+
+        @PreDestroy
+        public void destroy() {
+            repository.writeApplicationStatus("Closing application");
+        }
+    }
+
+    @Test
+    public void testDestroyOrder() {
+
+        // This test fails because Mycila destroys singletons in the order they are bound
+
+        CloseableInjector injector = Guice
+                .createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(Repository.class);
+                        bind(Service.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        injector.close();
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaInitDestroyBindingsTest.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/MycilaInitDestroyBindingsTest.java
new file mode 100755 (executable)
index 0000000..cf87eac
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Provider;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Singleton;
+import org.gaul.modernizer_maven_annotations.SuppressModernizer;
+import org.junit.Test;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+@SuppressModernizer
+public class MycilaInitDestroyBindingsTest {
+
+    public static class InitDestroyCounter {
+
+        public int initialized;
+        public int destroyed;
+
+        @PostConstruct
+        public void init() {
+            initialized++;
+        }
+
+        @PreDestroy
+        public void destroy() {
+            destroyed++;
+        }
+    }
+
+    public interface SomeInterface {
+    }
+
+    public interface AnotherInterface {
+    }
+
+    public static class NonScopedTestObject extends InitDestroyCounter implements SomeInterface, AnotherInterface {
+    }
+
+    @Singleton
+    public static class TestSingleton extends InitDestroyCounter implements SomeInterface, AnotherInterface {
+    }
+
+    public abstract static class TestProvider<T> extends InitDestroyCounter implements Provider<T> {
+    }
+
+    @Test
+    public void testUntargettedBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(TestSingleton.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        TestSingleton component = injector.getInstance(TestSingleton.class);
+        assertEquals(1, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(1, component.initialized);
+        assertEquals(1, component.destroyed);
+    }
+
+    @Test
+    public void testLinkedBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(SomeInterface.class).to(TestSingleton.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        TestSingleton component = (TestSingleton) injector.getInstance(SomeInterface.class);
+        assertEquals(1, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(1, component.initialized);
+        assertEquals(1, component.destroyed);
+
+        // Guice creates an internal jit ConstructorBinding therefor this fails as Mycila destroys on both bindings
+    }
+
+    @Test
+    public void testLinkedAndUntargettedBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(TestSingleton.class);
+                        bind(SomeInterface.class).to(TestSingleton.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        TestSingleton component = (TestSingleton) injector.getInstance(SomeInterface.class);
+        assertEquals(1, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(1, component.initialized);
+        assertEquals(1, component.destroyed);
+
+        // Both bindings return the same object therefor this fails as Mycila destroys on both bindings
+    }
+
+    @Test
+    public void testInstanceBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        TestSingleton instance = new TestSingleton();
+                        bind(SomeInterface.class).toInstance(instance);
+                        bind(AnotherInterface.class).toInstance(instance);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        TestSingleton component = (TestSingleton) injector.getInstance(SomeInterface.class);
+        assertEquals(1, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(1, component.initialized);
+        assertEquals(1, component.destroyed);
+
+        // Both bindings return the same object therefor this fails as Mycila destroys on both bindings
+    }
+
+    @Test
+    public void testNonSingletonInstanceBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        NonScopedTestObject instance = new NonScopedTestObject();
+                        bind(SomeInterface.class).toInstance(instance);
+                        bind(AnotherInterface.class).toInstance(instance);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        // The object is not scoped but Guice considers instance bindings to be singletons so Mycila will destroy it
+
+        NonScopedTestObject component = (NonScopedTestObject) injector.getInstance(SomeInterface.class);
+        assertEquals(1, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(1, component.initialized);
+        assertEquals(1, component.destroyed);
+
+        // Both bindings return the same object therefor this fails as Mycila destroys on both bindings
+    }
+
+    @Test
+    public void testProviderBinding() {
+        CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        final TestSingleton instance = new TestSingleton();
+                        bind(TestSingleton.class).toProvider(new Provider<TestSingleton>() {
+                            @Override
+                            public TestSingleton get() {
+                                return instance;
+                            }
+                        });
+                        bind(SomeInterface.class).toProvider(new Provider<SomeInterface>() {
+                            @Override
+                            public TestSingleton get() {
+                                return instance;
+                            }
+                        });
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        // Provider bindings are not scoped so Mycila will not destroy them
+
+        TestSingleton component = (TestSingleton) injector.getInstance(SomeInterface.class);
+        assertEquals(0, component.initialized);
+        assertEquals(0, component.destroyed);
+
+        injector.close();
+        assertEquals(0, component.initialized);
+        assertEquals(0, component.destroyed);
+    }
+
+    @Test
+    public void testProvider() {
+
+        final TestProvider<TestSingleton> testProvider1 = new TestProvider<TestSingleton>() {
+            @Override
+            public TestSingleton get() {
+                return new TestSingleton();
+            }
+        };
+        final TestProvider<SomeInterface> testProvider2 = new TestProvider<SomeInterface>() {
+            @Override
+            public TestSingleton get() {
+                return new TestSingleton();
+            }
+        };
+
+        final CloseableInjector injector = Guice
+                .createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+                    @Override
+                    protected void configure() {
+                        bind(TestSingleton.class).toProvider(testProvider1);
+                        bind(SomeInterface.class).toProvider(testProvider2).in(Singleton.class);
+                    }
+                }).getInstance(CloseableInjector.class);
+
+        // Guice will do injection on the provider but will not destroy it since its not singleton scoped
+
+        assertEquals(1, testProvider1.initialized);
+        assertEquals(0, testProvider1.destroyed);
+        assertEquals(1, testProvider2.initialized);
+        assertEquals(0, testProvider2.destroyed);
+
+        injector.close();
+
+        assertEquals(1, testProvider1.initialized);
+        assertEquals(0, testProvider1.destroyed);
+        assertEquals(1, testProvider2.initialized);
+        assertEquals(1, testProvider2.destroyed);
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Perf.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/Perf.java
new file mode 100755 (executable)
index 0000000..00f0170
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import javax.annotation.PostConstruct;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com) date 2013-07-06
+ */
+final class Perf {
+
+    private Perf() {
+    }
+
+    private static long invocations;
+
+    public static class TestClassWithPostConstruct {
+
+        public void method1() {
+        }
+
+        public void method2() {
+        }
+
+        @PostConstruct
+        public void method3() {
+            invocations++;
+        }
+
+        public void method4() {
+        }
+    }
+
+    public static class TestClassWithoutPostConstruct {
+
+        public void method1() {
+        }
+
+        public void method2() {
+        }
+
+        public void method3() {
+        }
+
+        public void method4() {
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+        // connect visual vm
+        Thread.sleep(10000);
+
+        int count = 1 * 1000 * 10000;
+
+        time("without Mycila", count, createSimpleInjector(), TestClassWithPostConstruct.class);
+        time("with Mycila", count, createInjectorWithMycila(), TestClassWithPostConstruct.class);
+
+        time("without Mycila", count, createSimpleInjector(), TestClassWithoutPostConstruct.class);
+        time("with Mycila", count, createInjectorWithMycila(), TestClassWithoutPostConstruct.class);
+    }
+
+    private static void time(String name, int count, Injector injector, Class<?> clazz) {
+
+        // warm up
+        for (int i = 0; i < 1000 * 1000; i++) {
+            injector.getInstance(clazz);
+        }
+
+        invocations = 0;
+        long start = System.currentTimeMillis();
+
+        for (int i = 0; i < count; i++) {
+            injector.getInstance(clazz);
+        }
+
+        long end = System.currentTimeMillis();
+    }
+
+    private static Injector createInjectorWithMycila() {
+        return Guice.createInjector(Stage.PRODUCTION, new Jsr250Module(), new CloseableModule());
+    }
+
+    private static Injector createSimpleInjector() {
+        return Guice.createInjector(Stage.PRODUCTION);
+    }
+}
diff --git a/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/PostConstructOnCyclicDependenciesTest.java b/inject/inject-guice-extensions/jsr250/src/test/java/org/opendaylight/odlguice/inject/guice/extensions/jsr250/tests/PostConstructOnCyclicDependenciesTest.java
new file mode 100755 (executable)
index 0000000..2898db2
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2010 Mycila (mathieu.carbou@gmail.com)
+ *
+ * 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 org.opendaylight.odlguice.inject.guice.extensions.jsr250.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.ProvisionException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
+
+/**
+ * This code originated in https://github.com/mycila/guice and was forked into
+ * OpenDaylight.
+ * @author Mathieu Carbou (mathieu.carbou@gmail.com)
+ */
+public class PostConstructOnCyclicDependenciesTest {
+    CloseableInjector inj;
+
+    @Before
+    public void setUp() throws Exception {
+        inj = Guice.createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
+            @Override
+            protected void configure() {
+                bind(A.class).to(AImpl.class);
+                bind(B.class).to(BImpl.class);
+            }
+        }).getInstance(CloseableInjector.class);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        CloseableInjector dying = inj;
+        inj = null;
+        dying.close();
+    }
+
+    @Test
+    public void testPostConstructOnCyclicDependency() {
+        A obj = null;
+        try {
+            obj = inj.getInstance(A.class);
+        } catch (ProvisionException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(obj);
+        assertTrue(obj.hasBeenCalled());
+    }
+}
diff --git a/inject/inject-guice-extensions/pom.xml b/inject/inject-guice-extensions/pom.xml
new file mode 100644 (file)
index 0000000..ce6af50
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!--
+ Copyright © 2019 Lumina, 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.opendaylight.odlguice</groupId>
+    <artifactId>parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../../common/parent</relativePath>
+  </parent>
+
+  <artifactId>inject.guice.extensions</artifactId>
+  <packaging>pom</packaging>
+  <!-- <name> formatting is used by autorelease to parse and notify projects on
+       build failure. Please do not modify this unless you have a good reason. -->
+  <name>ODL :: odlguice :: ${project.artifactId}</name>
+
+  <modules>
+    <module>closeable</module>
+    <module>injection</module>
+    <module>jsr250</module>
+  </modules>
+
+</project>
index 9e21f7e408244310debc6fea957ec80b48672ddd..1bb51f8349e97dc553cbba7dd42eac32cb2e4006 100644 (file)
       <artifactId>junit</artifactId>
       <scope>compile</scope>
     </dependency>
-    <dependency>
-      <groupId>com.mycila.guice.extensions</groupId>
-      <artifactId>mycila-guice-jsr250</artifactId>
-      <scope>compile</scope>
-    </dependency>
     <dependency>
       <groupId>com.google.inject</groupId>
       <artifactId>guice</artifactId>
       <artifactId>inject</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.odlguice</groupId>
+      <artifactId>inject.guice.extensions.jsr250</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        <dependency>
+      <groupId>org.opendaylight.odlguice</groupId>
+      <artifactId>inject.guice.extensions.closeable</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
   </dependencies>
 </project>
index 8c24ccd7f9f0c7ea13aa92a302e4379cdb63654f..65eabbe58da1041d6f25a73c17c97236e20fc250 100644 (file)
@@ -8,8 +8,8 @@
 package org.opendaylight.infrautils.inject.guice.testutils;
 
 import com.google.inject.AbstractModule;
-import com.mycila.guice.ext.closeable.CloseableModule;
-import com.mycila.guice.ext.jsr250.Jsr250Module;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
 
 /**
  * Guice module with built-in Mycila Guice Extensions for JSR-250 &amp;
index c9421a04e6788accd1b990ad0f021bfc1dbc99d3..4d46b8e1bb026cea16183e7e3a3199a219969f14 100644 (file)
@@ -12,7 +12,6 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.google.inject.Stage;
-import com.mycila.guice.ext.closeable.CloseableInjector;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -20,6 +19,7 @@ import org.junit.rules.MethodRule;
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
 import org.opendaylight.infrautils.inject.PostFullSystemInjectionListener;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableInjector;
 
 /**
  * JUnit Rule which initializes Guice {@link Injector} for tests.
index aca9a4e10aa05e247decbb1232da73aff3ec089c..0d2a9cdc0919bf819b382a62275fe445711e2838 100644 (file)
@@ -12,9 +12,9 @@ import static org.junit.Assert.assertTrue;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.mycila.guice.ext.closeable.CloseableModule;
-import com.mycila.guice.ext.jsr250.Jsr250Module;
 import org.junit.Test;
+import org.opendaylight.odlguice.inject.guice.extensions.closeable.CloseableModule;
+import org.opendaylight.odlguice.inject.guice.extensions.jsr250.Jsr250Module;
 
 /**
  * Example Guice Test without using Rule, just for illustration.
index 505cf2933a79374e2561e18ffa9f952fbea8810d..46a6c91ea72bc25a4cea995b3304b85e13852a23 100644 (file)
@@ -15,7 +15,7 @@
       <version>1.0.0-SNAPSHOT</version>
       <relativePath>../../common/parent</relativePath>
   </parent>
-  
+
   <artifactId>inject.guice</artifactId>
   <packaging>bundle</packaging>
   <!-- <name> formatting is used by autorelease to parse and notify projects on
   <name>ODL :: odlguice :: ${project.artifactId}</name>
 
   <dependencies>
+    <dependency>
+      <groupId>javax.annotation</groupId>
+      <artifactId>javax.annotation-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>javax.inject</groupId>
       <artifactId>javax.inject</artifactId>
       <!-- Important to enforce false because in odlparent it's true (see gerrit/c/56723) -->
       <optional>false</optional>
     </dependency>
-    <dependency>
-      <groupId>com.mycila.guice.extensions</groupId>
-      <artifactId>mycila-guice-jsr250</artifactId>
-    </dependency>
     <dependency>
       <groupId>com.google.inject</groupId>
       <artifactId>guice</artifactId>
       <version>${project.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.odlguice</groupId>
+      <artifactId>inject.guice.extensions.jsr250</artifactId>
+      <version>${project.version}</version>
+    </dependency>
   </dependencies>
 </project>
index 6239dbeafabc98bd23d069642f1a632da23a736e..d2c8ad6e017c47a8ecc28bfd72412207db7915c1 100644 (file)
@@ -29,5 +29,6 @@
     <module>inject</module>
     <module>inject-guice</module>
     <module>inject-guice-testutils</module>
+    <module>inject-guice-extensions</module>
   </modules>
 </project>