001/*
002 * Copyright 2012-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 *      http://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.boot.autoconfigure.condition;
018
019import org.springframework.util.Assert;
020import org.springframework.util.ObjectUtils;
021
022/**
023 * Outcome for a condition match, including log message.
024 *
025 * @author Phillip Webb
026 * @see ConditionMessage
027 */
028public class ConditionOutcome {
029
030        private final boolean match;
031
032        private final ConditionMessage message;
033
034        /**
035         * Create a new {@link ConditionOutcome} instance. For more consistent messages
036         * consider using {@link #ConditionOutcome(boolean, ConditionMessage)}.
037         * @param match if the condition is a match
038         * @param message the condition message
039         */
040        public ConditionOutcome(boolean match, String message) {
041                this(match, ConditionMessage.of(message));
042        }
043
044        /**
045         * Create a new {@link ConditionOutcome} instance.
046         * @param match if the condition is a match
047         * @param message the condition message
048         */
049        public ConditionOutcome(boolean match, ConditionMessage message) {
050                Assert.notNull(message, "ConditionMessage must not be null");
051                this.match = match;
052                this.message = message;
053        }
054
055        /**
056         * Create a new {@link ConditionOutcome} instance for a 'match'.
057         * @return the {@link ConditionOutcome}
058         */
059        public static ConditionOutcome match() {
060                return match(ConditionMessage.empty());
061        }
062
063        /**
064         * Create a new {@link ConditionOutcome} instance for 'match'. For more consistent
065         * messages consider using {@link #match(ConditionMessage)}.
066         * @param message the message
067         * @return the {@link ConditionOutcome}
068         */
069        public static ConditionOutcome match(String message) {
070                return new ConditionOutcome(true, message);
071        }
072
073        /**
074         * Create a new {@link ConditionOutcome} instance for 'match'.
075         * @param message the message
076         * @return the {@link ConditionOutcome}
077         */
078        public static ConditionOutcome match(ConditionMessage message) {
079                return new ConditionOutcome(true, message);
080        }
081
082        /**
083         * Create a new {@link ConditionOutcome} instance for 'no match'. For more consistent
084         * messages consider using {@link #noMatch(ConditionMessage)}.
085         * @param message the message
086         * @return the {@link ConditionOutcome}
087         */
088        public static ConditionOutcome noMatch(String message) {
089                return new ConditionOutcome(false, message);
090        }
091
092        /**
093         * Create a new {@link ConditionOutcome} instance for 'no match'.
094         * @param message the message
095         * @return the {@link ConditionOutcome}
096         */
097        public static ConditionOutcome noMatch(ConditionMessage message) {
098                return new ConditionOutcome(false, message);
099        }
100
101        /**
102         * Return {@code true} if the outcome was a match.
103         * @return {@code true} if the outcome matches
104         */
105        public boolean isMatch() {
106                return this.match;
107        }
108
109        /**
110         * Return an outcome message or {@code null}.
111         * @return the message or {@code null}
112         */
113        public String getMessage() {
114                return this.message.isEmpty() ? null : this.message.toString();
115        }
116
117        /**
118         * Return an outcome message or {@code null}.
119         * @return the message or {@code null}
120         */
121        public ConditionMessage getConditionMessage() {
122                return this.message;
123        }
124
125        @Override
126        public boolean equals(Object obj) {
127                if (this == obj) {
128                        return true;
129                }
130                if (obj == null) {
131                        return false;
132                }
133                if (getClass() == obj.getClass()) {
134                        ConditionOutcome other = (ConditionOutcome) obj;
135                        return (this.match == other.match
136                                        && ObjectUtils.nullSafeEquals(this.message, other.message));
137                }
138                return super.equals(obj);
139        }
140
141        @Override
142        public int hashCode() {
143                return Boolean.hashCode(this.match) * 31
144                                + ObjectUtils.nullSafeHashCode(this.message);
145        }
146
147        @Override
148        public String toString() {
149                return (this.message != null) ? this.message.toString() : "";
150        }
151
152        /**
153         * Return the inverse of the specified condition outcome.
154         * @param outcome the outcome to inverse
155         * @return the inverse of the condition outcome
156         * @since 1.3.0
157         */
158        public static ConditionOutcome inverse(ConditionOutcome outcome) {
159                return new ConditionOutcome(!outcome.isMatch(), outcome.getConditionMessage());
160        }
161
162}