1 package net.sourceforge.pmd.properties;
2
3 import java.util.Map;
4
5 import net.sourceforge.pmd.util.CollectionUtil;
6 import net.sourceforge.pmd.util.StringUtil;
7
8 /**
9 * Defines a datatype with a set of preset values of any type as held within a pair of
10 * maps. While the values are not serialized out, the labels are and serve as keys to
11 * obtain the values.
12 *
13 * @author Brian Remedios
14 * @version $Revision$
15 */
16 public class EnumeratedProperty<E> extends AbstractPMDProperty {
17
18 private Map<String, E> choicesByLabel;
19 private Map<E, String> labelsByChoice;
20
21 /**
22 * Constructor for EnumeratedProperty.
23 * @param theName String
24 * @param theDescription String
25 * @param theLabels String[]
26 * @param theChoices E[]
27 * @param theUIOrder float
28 */
29 public EnumeratedProperty(String theName, String theDescription, String[] theLabels, E[] theChoices, float theUIOrder) {
30 this(theName, theDescription, theLabels, theChoices, theUIOrder, 1);
31 }
32
33 /**
34 * Constructor for EnumeratedProperty.
35 * @param theName String
36 * @param theDescription String
37 * @param theLabels String[]
38 * @param theChoices E[]
39 * @param theUIOrder float
40 * @param maxValues int
41 */
42 public EnumeratedProperty(String theName, String theDescription, String[] theLabels, E[] theChoices, float theUIOrder, int maxValues) {
43 super(theName, theDescription, theChoices[0], theUIOrder);
44
45 choicesByLabel = CollectionUtil.mapFrom(theLabels, theChoices);
46 labelsByChoice = CollectionUtil.invertedMapFrom(choicesByLabel);
47
48 maxValueCount(maxValues);
49 }
50
51 /**
52 * Method type.
53 * @return Class
54 * @see net.sourceforge.pmd.PropertyDescriptor#type()
55 */
56 public Class<Object> type() {
57 return Object.class;
58 }
59
60 private String nonLegalValueMsgFor(Object value) {
61 return "" + value + " is not a legal value";
62 }
63
64 /**
65 * Method errorFor.
66 * @param value Object
67 * @return String
68 * @see net.sourceforge.pmd.PropertyDescriptor#errorFor(Object)
69 */
70 public String errorFor(Object value) {
71
72 if (maxValueCount() == 1) {
73 return labelsByChoice.containsKey(value) ?
74 null : nonLegalValueMsgFor(value);
75 }
76
77 Object[] values = (Object[])value;
78 for (int i=0; i<values.length; i++) {
79 if (labelsByChoice.containsKey(values[i])) continue;
80 return nonLegalValueMsgFor(values[i]);
81 }
82 return null;
83 }
84
85 /**
86 * Method choiceFrom.
87 * @param label String
88 * @return E
89 */
90 private E choiceFrom(String label) {
91 E result = choicesByLabel.get(label);
92 if (result != null) return result;
93 throw new IllegalArgumentException(label);
94 }
95
96 /**
97 * Method valueFrom.
98 * @param value String
99 * @return Object
100 * @throws IllegalArgumentException
101 * @see net.sourceforge.pmd.PropertyDescriptor#valueFrom(String)
102 */
103 public Object valueFrom(String value) throws IllegalArgumentException {
104
105 if (maxValueCount() == 1) return choiceFrom(value);
106
107 String[] strValues = StringUtil.substringsOf(value, multiValueDelimiter);
108
109 Object[] values = new Object[strValues.length];
110 for (int i=0;i<values.length; i++) values[i] = choiceFrom(strValues[i]);
111 return values;
112 }
113
114 /**
115 * Method asDelimitedString.
116 * @param value Object
117 * @return String
118 * @see net.sourceforge.pmd.PropertyDescriptor#asDelimitedString(Object)
119 */
120 public String asDelimitedString(Object value) {
121
122 if (maxValueCount() == 1) return labelsByChoice.get(value);
123
124 Object[] choices = (Object[])value;
125
126 StringBuffer sb = new StringBuffer();
127
128 sb.append(labelsByChoice.get(choices[0]));
129
130 for (int i=1; i<choices.length; i++) {
131 sb.append(multiValueDelimiter);
132 sb.append(labelsByChoice.get(choices[i]));
133 }
134
135 return sb.toString();
136 }
137 }