001/*
002 * Copyright 2002-2015 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.beans.propertyeditors;
018
019import java.beans.PropertyEditorSupport;
020
021import org.springframework.util.StringUtils;
022
023/**
024 * Property editor for Boolean/boolean properties.
025 *
026 * <p>This is not meant to be used as system PropertyEditor but rather as
027 * locale-specific Boolean editor within custom controller code, to parse
028 * UI-caused boolean strings into boolean properties of beans and check
029 * them in the UI form.
030 *
031 * <p>In web MVC code, this editor will typically be registered with
032 * {@code binder.registerCustomEditor} calls.
033 *
034 * @author Juergen Hoeller
035 * @since 10.06.2003
036 * @see org.springframework.validation.DataBinder#registerCustomEditor
037 */
038public class CustomBooleanEditor extends PropertyEditorSupport {
039
040        public static final String VALUE_TRUE = "true";
041        public static final String VALUE_FALSE = "false";
042
043        public static final String VALUE_ON = "on";
044        public static final String VALUE_OFF = "off";
045
046        public static final String VALUE_YES = "yes";
047        public static final String VALUE_NO = "no";
048
049        public static final String VALUE_1 = "1";
050        public static final String VALUE_0 = "0";
051
052
053        private final String trueString;
054
055        private final String falseString;
056
057        private final boolean allowEmpty;
058
059
060        /**
061         * Create a new CustomBooleanEditor instance, with "true"/"on"/"yes"
062         * and "false"/"off"/"no" as recognized String values.
063         * <p>The "allowEmpty" parameter states if an empty String should
064         * be allowed for parsing, i.e. get interpreted as null value.
065         * Else, an IllegalArgumentException gets thrown in that case.
066         * @param allowEmpty if empty strings should be allowed
067         */
068        public CustomBooleanEditor(boolean allowEmpty) {
069                this(null, null, allowEmpty);
070        }
071
072        /**
073         * Create a new CustomBooleanEditor instance,
074         * with configurable String values for true and false.
075         * <p>The "allowEmpty" parameter states if an empty String should
076         * be allowed for parsing, i.e. get interpreted as null value.
077         * Else, an IllegalArgumentException gets thrown in that case.
078         * @param trueString the String value that represents true:
079         * for example, "true" (VALUE_TRUE), "on" (VALUE_ON),
080         * "yes" (VALUE_YES) or some custom value
081         * @param falseString the String value that represents false:
082         * for example, "false" (VALUE_FALSE), "off" (VALUE_OFF),
083         * "no" (VALUE_NO) or some custom value
084         * @param allowEmpty if empty strings should be allowed
085         * @see #VALUE_TRUE
086         * @see #VALUE_FALSE
087         * @see #VALUE_ON
088         * @see #VALUE_OFF
089         * @see #VALUE_YES
090         * @see #VALUE_NO
091         */
092        public CustomBooleanEditor(String trueString, String falseString, boolean allowEmpty) {
093                this.trueString = trueString;
094                this.falseString = falseString;
095                this.allowEmpty = allowEmpty;
096        }
097
098
099        @Override
100        public void setAsText(String text) throws IllegalArgumentException {
101                String input = (text != null ? text.trim() : null);
102                if (this.allowEmpty && !StringUtils.hasLength(input)) {
103                        // Treat empty String as null value.
104                        setValue(null);
105                }
106                else if (this.trueString != null && this.trueString.equalsIgnoreCase(input)) {
107                        setValue(Boolean.TRUE);
108                }
109                else if (this.falseString != null && this.falseString.equalsIgnoreCase(input)) {
110                        setValue(Boolean.FALSE);
111                }
112                else if (this.trueString == null &&
113                                (VALUE_TRUE.equalsIgnoreCase(input) || VALUE_ON.equalsIgnoreCase(input) ||
114                                                VALUE_YES.equalsIgnoreCase(input) || VALUE_1.equals(input))) {
115                        setValue(Boolean.TRUE);
116                }
117                else if (this.falseString == null &&
118                                (VALUE_FALSE.equalsIgnoreCase(input) || VALUE_OFF.equalsIgnoreCase(input) ||
119                                                VALUE_NO.equalsIgnoreCase(input) || VALUE_0.equals(input))) {
120                        setValue(Boolean.FALSE);
121                }
122                else {
123                        throw new IllegalArgumentException("Invalid boolean value [" + text + "]");
124                }
125        }
126
127        @Override
128        public String getAsText() {
129                if (Boolean.TRUE.equals(getValue())) {
130                        return (this.trueString != null ? this.trueString : VALUE_TRUE);
131                }
132                else if (Boolean.FALSE.equals(getValue())) {
133                        return (this.falseString != null ? this.falseString : VALUE_FALSE);
134                }
135                else {
136                        return "";
137                }
138        }
139
140}