--- /dev/null
+<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.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ <relativePath />
+ </parent>
+
+ <groupId>org.opendaylight.infrautils</groupId>
+ <artifactId>inject</artifactId>
+ <version>1.1.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ org.opendaylight.infrautils.inject
+ </Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- TODO Remove this when https://git.opendaylight.org/gerrit/#/c/44502/ is merged -->
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <version>1</version>
+ </dependency>
+ </dependencies>
+
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject;
+
+import java.util.concurrent.atomic.AtomicReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Support class for {@link Lifecycle}. Provides a convenient base
+ * implementation including correct thread safety, exception handling and check
+ * for accidental unnecessary re-start & stop. Subclasses must implement
+ * {@link #start()} & {@link #stop()}.
+ *
+ * @author Michael Vorburger (with guidance re. AtomicReference from Tom Pantelis)
+ */
+public abstract class AbstractLifecycle implements Lifecycle {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractLifecycle.class);
+
+ private enum State {
+ STARTED, STOPPED
+ }
+
+ private AtomicReference<State> state = new AtomicReference<>(State.STOPPED);
+
+ protected abstract void start() throws Exception;
+
+ protected abstract void stop() throws Exception;
+
+ /**
+ * Please implement {@link #start()} instead of overriding this (here intentionally final) method.
+ */
+ @Override
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ public final void init() throws ModuleSetupRuntimeException {
+ if (state.compareAndSet(State.STOPPED, State.STARTED)) {
+ try {
+ start();
+ } catch (Exception e) {
+ throw new ModuleSetupRuntimeException(e);
+ }
+ } else {
+ LOG.warn("Lifecycled object already started; ignoring start()");
+ }
+ }
+
+ /**
+ * Please implement {@link #stop()} instead of overriding this (here intentionally final) method.
+ */
+ @Override
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ public final void destroy() throws ModuleSetupRuntimeException {
+ if (state.compareAndSet(State.STARTED, State.STOPPED)) {
+ try {
+ stop();
+ } catch (Exception e) {
+ throw new ModuleSetupRuntimeException(e);
+ }
+ } else {
+ LOG.warn("Lifecycled object already stopped; ignoring stop()");
+ }
+ }
+
+ @Override
+ public boolean isRunning() {
+ return state.get() == State.STARTED;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+/**
+ * Something which can be {@link #init()}-ialized and {@link #destroy()}-d.
+ *
+ * <p>Annotated so that Dependency Injection Frameworks (whichever) automatically call these methods during wiring.
+ *
+ * @see AbstractLifecycle
+ * @see SingletonWithLifecycle
+ *
+ * @author Michael Vorburger
+ */
+public interface Lifecycle {
+
+ @PostConstruct
+ void init() throws ModuleSetupRuntimeException;
+
+ @PreDestroy
+ void destroy() throws ModuleSetupRuntimeException;
+
+ boolean isRunning();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject;
+
+/**
+ * Exception to throw from a static Dependency Inject Framework's "Wiring" class.
+ *
+ * <p>Also used in {@link Lifecycle#init()} and {@link Lifecycle#destroy()}, because
+ * those methods are typically called from DI's Wiring classes (typically implicitly
+ * by a DI framework, and not hand-written Wiring code).
+ *
+ * <p>For example, throw this from methods in a class implementing Guice's Module
+ * interface, or from methods annotated with Dagger's @Provides in a @Module
+ * class, which <i>"may only throw unchecked exceptions"</i>. In particular, when you
+ * have to catch checked exceptions while creating objects, wrap them into this
+ * unchecked Exception.
+ *
+ * <p>When you use this Exception in a Dagger/Guice/etc. Module, you should
+ * probably write a simple test for the Module, just to verify it (alone) works
+ * at run-time (if there is a checked exception to catch, it probably
+ * initializes something that is non-trivial and could fail; so best to have a
+ * non-regression test for that Module).
+ *
+ * @author Michael Vorburger
+ */
+public class ModuleSetupRuntimeException extends RuntimeException {
+
+ private static final long serialVersionUID = -1795982967617796415L;
+
+ public ModuleSetupRuntimeException(Exception cause) {
+ super(cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.infrautils.inject;
+
+import javax.inject.Scope;
+import javax.inject.Singleton;
+
+/**
+ * A Singleton AbstractLifecycle.
+ *
+ * <p>In ODL, most wired objects ("beans") are {@link Singleton}, and it therefore
+ * makes sense to have this class and let both exposed Services and wired
+ * objects internal to bundles extend this.
+ *
+ * <p>Future use of DI in ODL may introduce additional non-{@link Singleton} {@link Scope}s.
+ *
+ * @author Michael Vorburger
+ */
+@Singleton
+public abstract class SingletonWithLifecycle extends AbstractLifecycle {
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * The interfaces and classes in this package are "for convenience". Technically
+ * you do NOT have to implement or extend any of these to work with Dependency
+ * Injection - and could instead just apply these annotations to a class
+ * yourself etc. But defining this once and encouraging projects to use this
+ * establishes uniformity, which also helps other reading your code to recognize
+ * a class as being of the respective kind.
+ */
+package org.opendaylight.infrautils.inject;
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=2 tabstop=2: -->
+<!--
+ Copyright © 2016 Red Hat, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<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.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.8.0-SNAPSHOT</version>
+ <relativePath />
+ </parent>
+
+ <groupId>org.opendaylight.infrautils</groupId>
+ <artifactId>inject-aggregator</artifactId>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>inject</module>
+ </modules>
+
+ <!--
+ Maven Site Configuration
+
+ The following configuration is necessary for maven-site-plugin to
+ correctly identify the correct deployment path for OpenDaylight Maven
+ sites.
+ -->
+ <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+ <distributionManagement>
+ <site>
+ <id>opendaylight-site</id>
+ <url>${nexus.site.url}/${project.artifactId}/</url>
+ </site>
+ </distributionManagement>
+</project>