1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.beanutils.converters;
20
21
22 import java.io.IOException;
23 import java.io.StreamTokenizer;
24 import java.io.StringReader;
25 import java.util.ArrayList;
26 import java.util.List;
27 import org.apache.commons.beanutils.ConversionException;
28 import org.apache.commons.beanutils.Converter;
29
30
31
32 /***
33 * <p>Convenience base class for converters that translate the String
34 * representation of an array into a corresponding array of primitives
35 * object. This class encapsulates the functionality required to parse
36 * the String into a list of String elements that can later be
37 * individually converted to the appropriate primitive type.</p>
38 *
39 * <p>The input syntax accepted by the <code>parseElements()</code> method
40 * is designed to be compatible with the syntax used to initialize arrays
41 * in a Java source program, except that only String literal values are
42 * supported. For maximum flexibility, the surrounding '{' and '}'
43 * characters are optional, and individual elements may be separated by
44 * any combination of whitespace and comma characters.</p>
45 *
46 * @author Craig R. McClanahan
47 * @version $Revision: 557808 $ $Date: 2007-07-20 00:05:03 +0100 (Fri, 20 Jul 2007) $
48 * @since 1.4
49 * @deprecated Replaced by the new {@link ArrayConverter} implementation
50 */
51
52 public abstract class AbstractArrayConverter implements Converter {
53
54
55
56
57
58 /***
59 * Create a {@link Converter} that will throw a {@link ConversionException}
60 * if a conversion error occurs.
61 */
62 public AbstractArrayConverter() {
63
64 this.defaultValue = null;
65 this.useDefault = false;
66
67 }
68
69 /***
70 * Create a {@link Converter} that will return the specified default value
71 * if a conversion error occurs.
72 *
73 * @param defaultValue The default value to be returned
74 */
75 public AbstractArrayConverter(Object defaultValue) {
76
77 if (defaultValue == NO_DEFAULT) {
78 this.useDefault = false;
79 } else {
80 this.defaultValue = defaultValue;
81 this.useDefault = true;
82 }
83
84 }
85
86
87
88 /***
89 * This is a special reference that can be passed as the "default object"
90 * to the constructor to indicate that no default is desired. Note that
91 * the value 'null' cannot be used for this purpose, as the caller may
92 * want a null to be returned as the default.
93 */
94 public static final Object NO_DEFAULT = new Object();
95
96
97
98
99 /***
100 * <p>Model object for string arrays.</p>
101 */
102 protected static String[] strings = new String[0];
103
104
105 /***
106 * The default value specified to our Constructor, if any.
107 */
108 protected Object defaultValue = null;
109
110
111 /***
112 * Should we return the default value on conversion errors?
113 */
114 protected boolean useDefault = true;
115
116
117
118
119
120 /***
121 * Convert the specified input object into an output object of the
122 * specified type. This method must be implemented by a concrete
123 * subclass.
124 *
125 * @param type Data type to which this value should be converted
126 * @param value The input value to be converted
127 * @return The converted value
128 *
129 * @exception ConversionException if conversion cannot be performed
130 * successfully
131 */
132 public abstract Object convert(Class type, Object value);
133
134
135
136
137
138 /***
139 * <p>Parse an incoming String of the form similar to an array initializer
140 * in the Java language into a <code>List</code> individual Strings
141 * for each element, according to the following rules.</p>
142 * <ul>
143 * <li>The string is expected to be a comma-separated list of values.</li>
144 * <li>The string may optionally have matching '{' and '}' delimiters
145 * around the list.</li>
146 * <li>Whitespace before and after each element is stripped.</li>
147 * <li>Elements in the list may be delimited by single or double quotes.
148 * Within a quoted elements, the normal Java escape sequences are valid.</li>
149 * </ul>
150 *
151 * @param svalue String value to be parsed
152 * @return The parsed list of String values
153 *
154 * @exception ConversionException if the syntax of <code>svalue</code>
155 * is not syntactically valid
156 * @exception NullPointerException if <code>svalue</code>
157 * is <code>null</code>
158 */
159 protected List parseElements(String svalue) {
160
161
162 if (svalue == null) {
163 throw new NullPointerException();
164 }
165
166
167 svalue = svalue.trim();
168 if (svalue.startsWith("{") && svalue.endsWith("}")) {
169 svalue = svalue.substring(1, svalue.length() - 1);
170 }
171
172 try {
173
174
175 StreamTokenizer st =
176 new StreamTokenizer(new StringReader(svalue));
177 st.whitespaceChars(',',',');
178 st.ordinaryChars('0', '9');
179 st.ordinaryChars('.', '.');
180 st.ordinaryChars('-', '-');
181 st.wordChars('0', '9');
182 st.wordChars('.', '.');
183 st.wordChars('-', '-');
184
185
186 ArrayList list = new ArrayList();
187 while (true) {
188 int ttype = st.nextToken();
189 if ((ttype == StreamTokenizer.TT_WORD) ||
190 (ttype > 0)) {
191 list.add(st.sval);
192 } else if (ttype == StreamTokenizer.TT_EOF) {
193 break;
194 } else {
195 throw new ConversionException
196 ("Encountered token of type " + ttype);
197 }
198 }
199
200
201 return (list);
202
203 } catch (IOException e) {
204
205 throw new ConversionException(e);
206
207 }
208
209
210
211 }
212
213
214 }