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