001/*
002 * Copyright 2002-2019 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.ObjectUtils;
023import org.springframework.util.StringUtils;
024
025/**
026 * Custom {@link java.beans.PropertyEditor} for String arrays.
027 *
028 * <p>Strings must be in CSV format, with a customizable separator.
029 * By default values in the result are trimmed of whitespace.
030 *
031 * @author Rod Johnson
032 * @author Juergen Hoeller
033 * @author Dave Syer
034 * @see org.springframework.util.StringUtils#delimitedListToStringArray
035 * @see org.springframework.util.StringUtils#arrayToDelimitedString
036 */
037public class StringArrayPropertyEditor extends PropertyEditorSupport {
038
039        /**
040         * Default separator for splitting a String: a comma (",").
041         */
042        public static final String DEFAULT_SEPARATOR = ",";
043
044
045        private final String separator;
046
047        @Nullable
048        private final String charsToDelete;
049
050        private final boolean emptyArrayAsNull;
051
052        private final boolean trimValues;
053
054
055        /**
056         * Create a new {@code StringArrayPropertyEditor} with the default separator
057         * (a comma).
058         * <p>An empty text (without elements) will be turned into an empty array.
059         */
060        public StringArrayPropertyEditor() {
061                this(DEFAULT_SEPARATOR, null, false);
062        }
063
064        /**
065         * Create a new {@code StringArrayPropertyEditor} with the given separator.
066         * <p>An empty text (without elements) will be turned into an empty array.
067         * @param separator the separator to use for splitting a {@link String}
068         */
069        public StringArrayPropertyEditor(String separator) {
070                this(separator, null, false);
071        }
072
073        /**
074         * Create a new {@code StringArrayPropertyEditor} with the given separator.
075         * @param separator the separator to use for splitting a {@link String}
076         * @param emptyArrayAsNull {@code true} if an empty String array
077         * is to be transformed into {@code null}
078         */
079        public StringArrayPropertyEditor(String separator, boolean emptyArrayAsNull) {
080                this(separator, null, emptyArrayAsNull);
081        }
082
083        /**
084         * Create a new {@code StringArrayPropertyEditor} with the given separator.
085         * @param separator the separator to use for splitting a {@link String}
086         * @param emptyArrayAsNull {@code true} if an empty String array
087         * is to be transformed into {@code null}
088         * @param trimValues {@code true} if the values in the parsed arrays
089         * are to be trimmed of whitespace (default is true)
090         */
091        public StringArrayPropertyEditor(String separator, boolean emptyArrayAsNull, boolean trimValues) {
092                this(separator, null, emptyArrayAsNull, trimValues);
093        }
094
095        /**
096         * Create a new {@code StringArrayPropertyEditor} with the given separator.
097         * @param separator the separator to use for splitting a {@link String}
098         * @param charsToDelete a set of characters to delete, in addition to
099         * trimming an input String. Useful for deleting unwanted line breaks:
100         * e.g. "\r\n\f" will delete all new lines and line feeds in a String.
101         * @param emptyArrayAsNull {@code true} if an empty String array
102         * is to be transformed into {@code null}
103         */
104        public StringArrayPropertyEditor(String separator, @Nullable String charsToDelete, boolean emptyArrayAsNull) {
105                this(separator, charsToDelete, emptyArrayAsNull, true);
106        }
107
108        /**
109         * Create a new {@code StringArrayPropertyEditor} with the given separator.
110         * @param separator the separator to use for splitting a {@link String}
111         * @param charsToDelete a set of characters to delete, in addition to
112         * trimming an input String. Useful for deleting unwanted line breaks:
113         * e.g. "\r\n\f" will delete all new lines and line feeds in a String.
114         * @param emptyArrayAsNull {@code true} if an empty String array
115         * is to be transformed into {@code null}
116         * @param trimValues {@code true} if the values in the parsed arrays
117         * are to be trimmed of whitespace (default is true)
118         */
119        public StringArrayPropertyEditor(
120                        String separator, @Nullable String charsToDelete, boolean emptyArrayAsNull, boolean trimValues) {
121
122                this.separator = separator;
123                this.charsToDelete = charsToDelete;
124                this.emptyArrayAsNull = emptyArrayAsNull;
125                this.trimValues = trimValues;
126        }
127
128        @Override
129        public void setAsText(String text) throws IllegalArgumentException {
130                String[] array = StringUtils.delimitedListToStringArray(text, this.separator, this.charsToDelete);
131                if (this.emptyArrayAsNull && array.length == 0) {
132                        setValue(null);
133                }
134                else {
135                        if (this.trimValues) {
136                                array = StringUtils.trimArrayElements(array);
137                        }
138                        setValue(array);
139                }
140        }
141
142        @Override
143        public String getAsText() {
144                return StringUtils.arrayToDelimitedString(ObjectUtils.toObjectArray(getValue()), this.separator);
145        }
146
147}