001/*
002 * Copyright 2006-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.batch.core;
018
019/**
020 * Enumeration representing the status of an Execution.
021 * 
022 * @author Lucas Ward
023 * @author Dave Syer
024 * @author Michael Minella
025 * @author Mahmoud Ben Hassine
026 */
027public enum BatchStatus {
028
029        /**
030         * The order of the status values is significant because it can be used to
031         * aggregate a set of status values - the result should be the maximum
032         * value. Since COMPLETED is first in the order, only if all elements of an
033         * execution are COMPLETED will the aggregate status be COMPLETED. A running
034         * execution is expected to move from STARTING to STARTED to COMPLETED
035         * (through the order defined by {@link #upgradeTo(BatchStatus)}). Higher
036         * values than STARTED signify more serious failure. ABANDONED is used for
037         * steps that have finished processing, but were not successful, and where
038         * they should be skipped on a restart (so FAILED is the wrong status).
039         */
040        COMPLETED, STARTING, STARTED, STOPPING, STOPPED, FAILED, ABANDONED, UNKNOWN;
041
042        public static BatchStatus max(BatchStatus status1, BatchStatus status2) {
043                return status1.isGreaterThan(status2) ? status1 : status2;
044        }
045
046        /**
047         * Convenience method to decide if a status indicates work is in progress.
048         * 
049         * @return true if the status is STARTING, STARTED
050         */
051        public boolean isRunning() {
052                return this == STARTING || this == STARTED;
053        }
054
055        /**
056         * Convenience method to decide if a status indicates execution was
057         * unsuccessful.
058         * 
059         * @return true if the status is FAILED or greater
060         */
061        public boolean isUnsuccessful() {
062                return this == FAILED || this.isGreaterThan(FAILED);
063        }
064
065        /**
066         * Method used to move status values through their logical progression, and
067         * override less severe failures with more severe ones. This value is
068         * compared with the parameter and the one that has higher priority is
069         * returned. If both are STARTED or less than the value returned is the
070         * largest in the sequence STARTING, STARTED, COMPLETED. Otherwise the value
071         * returned is the maximum of the two.
072         * 
073         * @param other another status to compare to
074         * @return either this or the other status depending on their priority
075         */
076        public BatchStatus upgradeTo(BatchStatus other) {
077                if (isGreaterThan(STARTED) || other.isGreaterThan(STARTED)) {
078                        return max(this, other);
079                }
080                // Both less than or equal to STARTED
081                if (this == COMPLETED || other == COMPLETED) {
082                        return COMPLETED;
083                }
084                return max(this, other);
085        }
086
087        /**
088         * @param other a status value to compare
089         * @return true if this is greater than other
090         */
091        public boolean isGreaterThan(BatchStatus other) {
092                return this.compareTo(other) > 0;
093        }
094
095        /**
096         * @param other a status value to compare
097         * @return true if this is less than other
098         */
099        public boolean isLessThan(BatchStatus other) {
100                return this.compareTo(other) < 0;
101        }
102
103        /**
104         * @param other a status value to compare
105         * @return true if this is less than other
106         */
107        public boolean isLessThanOrEqualTo(BatchStatus other) {
108                return this.compareTo(other) <= 0;
109        }
110
111        /**
112         * Converts the current status to the JSR-352 equivalent
113         * 
114         * @return JSR-352 equivalent to the current status
115         */
116        public javax.batch.runtime.BatchStatus getBatchStatus() {
117                if(this == ABANDONED) {
118                        return javax.batch.runtime.BatchStatus.ABANDONED;
119                } else if(this == COMPLETED) {
120                        return javax.batch.runtime.BatchStatus.COMPLETED;
121                } else if(this == STARTED) {
122                        return javax.batch.runtime.BatchStatus.STARTED;
123                } else if(this == STARTING) {
124                        return javax.batch.runtime.BatchStatus.STARTING;
125                } else if(this == STOPPED) {
126                        return javax.batch.runtime.BatchStatus.STOPPED;
127                } else if(this == STOPPING) {
128                        return javax.batch.runtime.BatchStatus.STOPPING;
129                } else {
130                        return javax.batch.runtime.BatchStatus.FAILED;
131                }
132        }
133
134        /**
135         * Find a BatchStatus that matches the beginning of the given value. If no
136         * match is found, return COMPLETED as the default because has is low
137         * precedence.
138         * 
139         * @param value a string representing a status
140         * @return a BatchStatus
141         */
142        public static BatchStatus match(String value) {
143                for (BatchStatus status : values()) {
144                        if (value.startsWith(status.toString())) {
145                                return status;
146                        }
147                }
148                // Default match should be the lowest priority
149                return COMPLETED;
150        }
151}