001/*
002 * Copyright 2006-2013 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 */
016package org.springframework.batch.core.job.flow;
017
018/**
019 * Represents the status of {@link FlowExecution}.
020 *
021 * @author Dan Garrette
022 * @author Dave Syer
023 * @since 2.0
024 */
025public class FlowExecutionStatus implements Comparable<FlowExecutionStatus> {
026
027        /**
028         * Special well-known status value.
029         */
030        public static final FlowExecutionStatus COMPLETED = new FlowExecutionStatus(Status.COMPLETED.toString());
031
032        /**
033         * Special well-known status value.
034         */
035        public static final FlowExecutionStatus STOPPED = new FlowExecutionStatus(Status.STOPPED.toString());
036
037        /**
038         * Special well-known status value.
039         */
040        public static final FlowExecutionStatus FAILED = new FlowExecutionStatus(Status.FAILED.toString());
041
042        /**
043         * Special well-known status value.
044         */
045        public static final FlowExecutionStatus UNKNOWN = new FlowExecutionStatus(Status.UNKNOWN.toString());
046
047        private final String name;
048
049        private enum Status {
050
051                COMPLETED, STOPPED, FAILED, UNKNOWN;
052
053                static Status match(String value) {
054                        for (int i = 0; i < values().length; i++) {
055                                Status status = values()[i];
056                                if (value.startsWith(status.toString())) {
057                                        return status;
058                                }
059                        }
060                        // Default match should be the lowest priority
061                        return COMPLETED;
062                }
063
064        }
065
066        /**
067         * @param status String status value.
068         */
069        public FlowExecutionStatus(String status) {
070                this.name = status;
071        }
072
073        /**
074         * @return true if the status starts with "STOPPED"
075         */
076        public boolean isStop() {
077                return name.startsWith(STOPPED.getName());
078        }
079
080        /**
081         * @return true if the status starts with "FAILED"
082         */
083        public boolean isFail() {
084                return name.startsWith(FAILED.getName());
085        }
086
087
088        /**
089         * @return true if this status represents the end of a flow
090         */
091        public boolean isEnd() {
092                return isStop() || isFail() || isComplete();
093        }
094
095        /**
096         * @return true if the status starts with "COMPLETED"
097         */
098        private boolean isComplete() {
099                return name.startsWith(COMPLETED.getName());
100        }
101        /**
102         * Create an ordering on {@link FlowExecutionStatus} instances by comparing
103         * their statuses.
104         *
105         * @see Comparable#compareTo(Object)
106         *
107         * @param other instance of {@link FlowExecutionStatus} to compare this instance with.
108         * @return negative, zero or positive as per the contract
109         */
110        @Override
111        public int compareTo(FlowExecutionStatus other) {
112                Status one = Status.match(this.name);
113                Status two = Status.match(other.name);
114                int comparison = one.compareTo(two);
115                if (comparison == 0) {
116                        return this.name.compareTo(other.name);
117                }
118                return comparison;
119        }
120
121        /**
122         * Check the equality of the statuses.
123         *
124         * @see java.lang.Object#equals(java.lang.Object)
125         */
126        @Override
127        public boolean equals(Object object) {
128                if (object == this) {
129                        return true;
130                }
131                if (!(object instanceof FlowExecutionStatus)) {
132                        return false;
133                }
134                FlowExecutionStatus other = (FlowExecutionStatus) object;
135                return name.equals(other.name);
136        }
137
138        @Override
139        public int hashCode() {
140                return name.hashCode();
141        }
142
143        /**
144         * @see Object#toString()
145         */
146        @Override
147        public String toString() {
148                return name;
149        }
150
151        /**
152         * @return the name of this status
153         */
154        public String getName() {
155                return name;
156        }
157
158}