All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.infrautils.inject.AbstractLifecycle Maven / Gradle / Ivy

/*
 * 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 javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
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 final AtomicReference 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
    @PostConstruct // NOTE: @PostConstruct is *NOT* inherited from interface, so must be here
    @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
    @PreDestroy // NOTE: @PostConstruct is *NOT* inherited from interface, so must be here
    @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;
    }

    protected void checkIsRunning() {
        if (!isRunning()) {
            throw new IllegalStateException("Lifecycled object is already stopped: " + this.toString());
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy