001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.net;
015
016import ch.qos.logback.core.spi.ContextAwareBase;
017import ch.qos.logback.core.spi.LifeCycle;
018
019/**
020 * An abstract base for components that receive logging events from a remote
021 * peer and log according to local policy
022 *
023 * @author Carl Harris
024 */
025public abstract class ReceiverBase extends ContextAwareBase implements LifeCycle {
026
027    private boolean started;
028
029    /**
030     * {@inheritDoc}
031     */
032    public final void start() {
033        if (isStarted())
034            return;
035        if (getContext() == null) {
036            throw new IllegalStateException("context not set");
037        }
038        if (shouldStart()) {
039            getContext().getScheduledExecutorService().execute(getRunnableTask());
040            started = true;
041        }
042    }
043
044    /**
045     * {@inheritDoc}
046     */
047    public final void stop() {
048        if (!isStarted())
049            return;
050        try {
051            onStop();
052        } catch (RuntimeException ex) {
053            addError("on stop: " + ex, ex);
054        }
055        started = false;
056    }
057
058    /**
059     * {@inheritDoc}
060     */
061    public final boolean isStarted() {
062        return started;
063    }
064
065    /**
066     * Determines whether this receiver should start.
067     * <p>
068     * Subclasses will implement this method to do any subclass-specific
069     * validation.  The subclass's {@link #getRunnableTask()} method will be 
070     * invoked (and the task returned will be submitted to the executor)
071     * if and only if this method returns {@code true} 
072     * @return flag indicating whether this receiver should start
073     */
074    protected abstract boolean shouldStart();
075
076    /**
077     * Allows a subclass to participate in receiver shutdown.
078     */
079    protected abstract void onStop();
080
081    /**
082     * Provides the runnable task this receiver will execute.
083     * @return runnable task
084     */
085    protected abstract Runnable getRunnableTask();
086
087}