1
2
3
4 package net.sourceforge.pmd.lang.rule.properties.factories;
5
6 import static net.sourceforge.pmd.PropertyDescriptorFields.DEFAULT_VALUE;
7 import static net.sourceforge.pmd.PropertyDescriptorFields.DELIMITER;
8 import static net.sourceforge.pmd.PropertyDescriptorFields.DESC;
9 import static net.sourceforge.pmd.PropertyDescriptorFields.LEGAL_PACKAGES;
10 import static net.sourceforge.pmd.PropertyDescriptorFields.MAX;
11 import static net.sourceforge.pmd.PropertyDescriptorFields.MIN;
12 import static net.sourceforge.pmd.PropertyDescriptorFields.NAME;
13
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.HashMap;
17 import java.util.List;
18 import java.util.Map;
19
20 import net.sourceforge.pmd.PropertyDescriptor;
21 import net.sourceforge.pmd.PropertyDescriptorFactory;
22 import net.sourceforge.pmd.lang.rule.properties.AbstractProperty;
23 import net.sourceforge.pmd.util.CollectionUtil;
24 import net.sourceforge.pmd.util.StringUtil;
25
26
27
28
29
30
31
32 public class BasicPropertyDescriptorFactory<T> implements PropertyDescriptorFactory {
33
34 private final Class<?> valueType;
35 private final Map<String, Boolean> fieldTypesByKey;
36
37 protected static final Map<String, Boolean> CORE_FIELD_TYPES_BY_KEY = CollectionUtil
38 .mapFrom(new String[] { NAME, DESC, DEFAULT_VALUE, DELIMITER }, new Boolean[] { Boolean.TRUE, Boolean.TRUE,
39 Boolean.TRUE, Boolean.FALSE });
40
41 public BasicPropertyDescriptorFactory(Class<?> theValueType) {
42 valueType = theValueType;
43 fieldTypesByKey = Collections.unmodifiableMap(CORE_FIELD_TYPES_BY_KEY);
44 }
45
46
47
48
49
50
51
52
53
54
55
56 public BasicPropertyDescriptorFactory(Class<?> theValueType, Map<String, Boolean> additionalFieldTypesByKey) {
57
58 valueType = theValueType;
59 Map<String, Boolean> temp = new HashMap<String, Boolean>(CORE_FIELD_TYPES_BY_KEY.size()
60 + additionalFieldTypesByKey.size());
61 temp.putAll(CORE_FIELD_TYPES_BY_KEY);
62 temp.putAll(additionalFieldTypesByKey);
63
64 fieldTypesByKey = Collections.unmodifiableMap(temp);
65 }
66
67 public Class<?> valueType() {
68 return valueType;
69 }
70
71 public PropertyDescriptor<?> createWith(Map<String, String> valuesById) {
72 throw new RuntimeException("Unimplemented createWith() method in subclass");
73 }
74
75 public Map<String, Boolean> expectedFields() {
76 return fieldTypesByKey;
77 }
78
79 protected String nameIn(Map<String, String> valuesById) {
80 return valuesById.get(NAME);
81 }
82
83 protected String descriptionIn(Map<String, String> valuesById) {
84 return valuesById.get(DESC);
85 }
86
87 protected String defaultValueIn(Map<String, String> valuesById) {
88 return valuesById.get(DEFAULT_VALUE);
89 }
90
91 protected String numericDefaultValueIn(Map<String, String> valuesById) {
92 String number = defaultValueIn(valuesById);
93 return StringUtil.isEmpty(number) ? "0" : number;
94
95
96 }
97
98 protected static String minValueIn(Map<String, String> valuesById) {
99 return valuesById.get(MIN);
100 }
101
102 protected static String maxValueIn(Map<String, String> valuesById) {
103 return valuesById.get(MAX);
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 protected static Boolean[] booleanValuesIn(String booleanString, char delimiter) {
123 String[] values = StringUtil.substringsOf(booleanString, delimiter);
124 Boolean[] result = new Boolean[values.length];
125 for (int i = 0; i < values.length; i++) {
126 result[i] = Boolean.valueOf(values[i]);
127 }
128 return result;
129 }
130
131 protected static Character[] charsIn(String charString, char delimiter) {
132 String[] values = StringUtil.substringsOf(charString, delimiter);
133 Character[] chars = new Character[values.length];
134
135 for (int i = 0; i < values.length; i++) {
136 if (values.length != 1) {
137 throw new IllegalArgumentException("missing/ambiguous character value");
138 }
139 chars[i] = values[i].charAt(0);
140 }
141 return chars;
142 }
143
144 protected static Integer[] integersIn(String numberString, char delimiter) {
145 String[] values = StringUtil.substringsOf(numberString, delimiter);
146 List<Integer> ints = new ArrayList<Integer>(values.length);
147 for (String value : values) {
148 try {
149 Integer newInt = Integer.parseInt(value);
150 ints.add(newInt);
151 } catch (Exception ex) {
152
153 }
154 }
155 return ints.toArray(new Integer[ints.size()]);
156 }
157
158 protected static Long[] longsIn(String numberString, char delimiter) {
159 String[] values = StringUtil.substringsOf(numberString, delimiter);
160 List<Long> longs = new ArrayList<Long>(values.length);
161 for (String value : values) {
162 try {
163 Long newLong = Long.parseLong(value);
164 longs.add(newLong);
165 } catch (Exception ex) {
166
167 }
168 }
169 return longs.toArray(new Long[longs.size()]);
170 }
171
172 protected static Float[] floatsIn(String numberString, char delimiter) {
173 String[] values = StringUtil.substringsOf(numberString, delimiter);
174 List<Float> floats = new ArrayList<Float>(values.length);
175 for (String value : values) {
176 try {
177 Float newFloat = Float.parseFloat(value);
178 floats.add(newFloat);
179 } catch (Exception ex) {
180
181 }
182 }
183 return floats.toArray(new Float[floats.size()]);
184 }
185
186 protected static Double[] doublesIn(String numberString, char delimiter) {
187 String[] values = StringUtil.substringsOf(numberString, delimiter);
188 List<Double> doubles = new ArrayList<Double>(values.length);
189 for (String value : values) {
190 try {
191 Double newDouble = Double.parseDouble(value);
192 doubles.add(newDouble);
193 } catch (Exception ex) {
194
195 }
196 }
197 return doubles.toArray(new Double[doubles.size()]);
198 }
199
200 protected static String[] labelsIn(Map<String, String> valuesById) {
201 return null;
202 }
203
204 protected static Object[] choicesIn(Map<String, String> valuesById) {
205 return null;
206 }
207
208 protected static int indexIn(Map<String, String> valuesById) {
209 return 0;
210 }
211
212 protected static int[] indiciesIn(Map<String, String> valuesById) {
213 return null;
214 }
215
216 protected static char delimiterIn(Map<String, String> valuesById) {
217 return delimiterIn(valuesById, AbstractProperty.DEFAULT_DELIMITER);
218 }
219
220 protected static char delimiterIn(Map<String, String> valuesById, char defaultDelimiter) {
221 String characterStr = "";
222 if (valuesById.containsKey(DELIMITER)) {
223 characterStr = valuesById.get(DELIMITER).trim();
224 }
225 if (characterStr.isEmpty()) {
226 return defaultDelimiter;
227 }
228 return characterStr.charAt(0);
229 }
230
231 protected static String[] minMaxFrom(Map<String, String> valuesById) {
232 String min = minValueIn(valuesById);
233 String max = maxValueIn(valuesById);
234 if (StringUtil.isEmpty(min) || StringUtil.isEmpty(max)) {
235 throw new RuntimeException("min and max values must be specified");
236 }
237 return new String[] { min, max };
238 }
239
240 protected static String[] legalPackageNamesIn(Map<String, String> valuesById, char delimiter) {
241 String names = valuesById.get(LEGAL_PACKAGES);
242 if (StringUtil.isEmpty(names)) {
243 return null;
244 }
245 return StringUtil.substringsOf(names, delimiter);
246 }
247
248 public static Map<String, Boolean> expectedFieldTypesWith(String[] otherKeys, Boolean[] otherValues) {
249 Map<String, Boolean> largerMap = new HashMap<String, Boolean>(otherKeys.length + CORE_FIELD_TYPES_BY_KEY.size());
250 largerMap.putAll(CORE_FIELD_TYPES_BY_KEY);
251 for (int i = 0; i < otherKeys.length; i++) {
252 largerMap.put(otherKeys[i], otherValues[i]);
253 }
254 return largerMap;
255 }
256
257
258
259
260
261
262
263
264
265
266 }