001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core;
018
019import java.util.concurrent.Future;
020import java.util.concurrent.TimeUnit;
021
022import org.apache.logging.log4j.status.StatusLogger;
023
024/**
025 * A life cycle to be extended.
026 * <p>
027 * Wraps a {@link LifeCycle.State}.
028 * </p>
029 */
030public class AbstractLifeCycle implements LifeCycle2 {
031
032    public static final int DEFAULT_STOP_TIMEOUT = 0;
033    public static final TimeUnit DEFAULT_STOP_TIMEUNIT = TimeUnit.MILLISECONDS;
034
035    /**
036     * Allow subclasses access to the status logger without creating another instance.
037     */
038    protected static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger();
039
040    /**
041     * Gets the status logger.
042     * 
043     * @return the status logger.
044     */
045    protected static org.apache.logging.log4j.Logger getStatusLogger() {
046        return LOGGER;
047    }
048
049    private volatile LifeCycle.State state = LifeCycle.State.INITIALIZED;
050
051    protected boolean equalsImpl(final Object obj) {
052        if (this == obj) {
053            return true;
054        }
055        if (obj == null) {
056            return false;
057        }
058        if (getClass() != obj.getClass()) {
059            return false;
060        }
061        final LifeCycle other = (LifeCycle) obj;
062        if (state != other.getState()) {
063            return false;
064        }
065        return true;
066    }
067
068    @Override
069    public LifeCycle.State getState() {
070        return this.state;
071    }
072
073    protected int hashCodeImpl() {
074        final int prime = 31;
075        int result = 1;
076        result = prime * result + ((state == null) ? 0 : state.hashCode());
077        return result;
078    }
079
080    public boolean isInitialized() {
081        return this.state == LifeCycle.State.INITIALIZED;
082    }
083
084    @Override
085    public boolean isStarted() {
086        return this.state == LifeCycle.State.STARTED;
087    }
088
089    public boolean isStarting() {
090        return this.state == LifeCycle.State.STARTING;
091    }
092
093    @Override
094    public boolean isStopped() {
095        return this.state == LifeCycle.State.STOPPED;
096    }
097
098    public boolean isStopping() {
099        return this.state == LifeCycle.State.STOPPING;
100    }
101
102    protected void setStarted() {
103        this.setState(LifeCycle.State.STARTED);
104    }
105
106    protected void setStarting() {
107        this.setState(LifeCycle.State.STARTING);
108    }
109
110    protected void setState(final LifeCycle.State newState) {
111        this.state = newState;
112        // Need a better string than this.toString() for the message
113        // LOGGER.trace("{} {}", this.state, this);
114    }
115
116    protected void setStopped() {
117        this.setState(LifeCycle.State.STOPPED);
118    }
119
120    protected void setStopping() {
121        this.setState(LifeCycle.State.STOPPING);
122    }
123
124    @Override
125    public void initialize() {
126        this.state = State.INITIALIZED;
127    }
128
129    @Override
130    public void start() {
131        this.setStarted();
132    }
133
134    @Override
135    public void stop() {
136        stop(DEFAULT_STOP_TIMEOUT, DEFAULT_STOP_TIMEUNIT);
137    }
138
139    protected boolean stop(final Future<?> future) {
140        boolean stopped = true;
141        if (future != null) {
142            if (future.isCancelled() || future.isDone()) {
143                return true;
144            }
145            stopped = future.cancel(true);
146        }
147        return stopped;
148    }
149
150    @Override
151    public boolean stop(final long timeout, final TimeUnit timeUnit) {
152        this.state = LifeCycle.State.STOPPED;
153        return true;
154    }
155
156}