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 java.lang.annotation.Documented;
020import java.lang.annotation.ElementType;
021import java.lang.annotation.Retention;
022import java.lang.annotation.RetentionPolicy;
023import java.lang.annotation.Target;
024
025import org.springframework.context.annotation.Conditional;
026import org.springframework.core.env.Environment;
027
028/**
029 * {@link Conditional} that checks if the specified properties have a specific value. By
030 * default the properties must be present in the {@link Environment} and
031 * <strong>not</strong> equal to {@code false}. The {@link #havingValue()} and
032 * {@link #matchIfMissing()} attributes allow further customizations.
033 * <p>
034 * The {@link #havingValue} attribute can be used to specify the value that the property
035 * should have. The table below shows when a condition matches according to the property
036 * value and the {@link #havingValue()} attribute:
037 *
038 * <table border="1">
039 * <caption>Having values</caption>
040 * <tr>
041 * <th>Property Value</th>
042 * <th>{@code havingValue=""}</th>
043 * <th>{@code havingValue="true"}</th>
044 * <th>{@code havingValue="false"}</th>
045 * <th>{@code havingValue="foo"}</th>
046 * </tr>
047 * <tr>
048 * <td>{@code "true"}</td>
049 * <td>yes</td>
050 * <td>yes</td>
051 * <td>no</td>
052 * <td>no</td>
053 * </tr>
054 * <tr>
055 * <td>{@code "false"}</td>
056 * <td>no</td>
057 * <td>no</td>
058 * <td>yes</td>
059 * <td>no</td>
060 * </tr>
061 * <tr>
062 * <td>{@code "foo"}</td>
063 * <td>yes</td>
064 * <td>no</td>
065 * <td>no</td>
066 * <td>yes</td>
067 * </tr>
068 * </table>
069 * <p>
070 * If the property is not contained in the {@link Environment} at all, the
071 * {@link #matchIfMissing()} attribute is consulted. By default missing attributes do not
072 * match.
073 * <p>
074 * This condition cannot be reliably used for matching collection properties. For example,
075 * in the following configuration, the condition matches if {@code spring.example.values}
076 * is present in the {@link Environment} but does not match if
077 * {@code spring.example.values[0]} is present.
078 *
079 * <pre class="code">
080 * &#064;ConditionalOnProperty(prefix = "spring", name = "example.values")
081 * class ExampleAutoConfiguration {
082 * }
083 * </pre>
084 *
085 * It is better to use a custom condition for such cases.
086 *
087 * @author Maciej Walkowiak
088 * @author Stephane Nicoll
089 * @author Phillip Webb
090 * @since 1.1.0
091 */
092@Retention(RetentionPolicy.RUNTIME)
093@Target({ ElementType.TYPE, ElementType.METHOD })
094@Documented
095@Conditional(OnPropertyCondition.class)
096public @interface ConditionalOnProperty {
097
098        /**
099         * Alias for {@link #name()}.
100         * @return the names
101         */
102        String[] value() default {};
103
104        /**
105         * A prefix that should be applied to each property. The prefix automatically ends
106         * with a dot if not specified. A valid prefix is defined by one or more words
107         * separated with dots (e.g. {@code "acme.system.feature"}).
108         * @return the prefix
109         */
110        String prefix() default "";
111
112        /**
113         * The name of the properties to test. If a prefix has been defined, it is applied to
114         * compute the full key of each property. For instance if the prefix is
115         * {@code app.config} and one value is {@code my-value}, the full key would be
116         * {@code app.config.my-value}
117         * <p>
118         * Use the dashed notation to specify each property, that is all lower case with a "-"
119         * to separate words (e.g. {@code my-long-property}).
120         * @return the names
121         */
122        String[] name() default {};
123
124        /**
125         * The string representation of the expected value for the properties. If not
126         * specified, the property must <strong>not</strong> be equal to {@code false}.
127         * @return the expected value
128         */
129        String havingValue() default "";
130
131        /**
132         * Specify if the condition should match if the property is not set. Defaults to
133         * {@code false}.
134         * @return if should match if the property is missing
135         */
136        boolean matchIfMissing() default false;
137
138}