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 extends AbstractPMDProperty {
17
18 private Object[][] choiceTuples;
19 private Map choicesByLabel;
20 private Map labelsByChoice;
21
22 /***
23 * Constructor for EnumeratedProperty.
24 * @param theName String
25 * @param theDescription String
26 * @param theChoices Object[][]
27 * @param theUIOrder float
28 */
29 public EnumeratedProperty(String theName, String theDescription, Object[][] theChoices, float theUIOrder) {
30 this(theName, theDescription, theChoices, theUIOrder, 1);
31 }
32
33 /***
34 * Constructor for EnumeratedProperty.
35 * @param theName String
36 * @param theDescription String
37 * @param theChoices Object[][]
38 * @param theUIOrder float
39 * @param maxValues int
40 */
41 public EnumeratedProperty(String theName, String theDescription, Object[][] theChoices, float theUIOrder, int maxValues) {
42 super(theName, theDescription, theChoices[0][1], theUIOrder);
43
44 choiceTuples = theChoices;
45 choicesByLabel = CollectionUtil.mapFrom(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 type() {
57 return Object.class;
58 }
59
60 /***
61 * Method choices.
62 * @return Object[][]
63 * @see net.sourceforge.pmd.PropertyDescriptor#choices()
64 */
65 public Object[][] choices() {
66 return choiceTuples;
67 }
68
69 private String nonLegalValueMsgFor(Object value) {
70 return "" + value + " is not a legal value";
71 }
72
73 /***
74 * Method errorFor.
75 * @param value Object
76 * @return String
77 * @see net.sourceforge.pmd.PropertyDescriptor#errorFor(Object)
78 */
79 public String errorFor(Object value) {
80
81 if (maxValueCount() == 1) {
82 return labelsByChoice.containsKey(value) ?
83 null : nonLegalValueMsgFor(value);
84 }
85
86 Object[] values = (Object[])value;
87 for (int i=0; i<values.length; i++) {
88 if (labelsByChoice.containsKey(values[i])) continue;
89 return nonLegalValueMsgFor(values[i]);
90 }
91 return null;
92 }
93
94 /***
95 * Method choiceFrom.
96 * @param label String
97 * @return Object
98 */
99 private Object choiceFrom(String label) {
100 Object result = choicesByLabel.get(label);
101 if (result != null) return result;
102 throw new IllegalArgumentException(label);
103 }
104
105 /***
106 * Method valueFrom.
107 * @param value String
108 * @return Object
109 * @throws IllegalArgumentException
110 * @see net.sourceforge.pmd.PropertyDescriptor#valueFrom(String)
111 */
112 public Object valueFrom(String value) throws IllegalArgumentException {
113
114 if (maxValueCount() == 1) return choiceFrom(value);
115
116 String[] strValues = StringUtil.substringsOf(value, multiValueDelimiter);
117
118 Object[] values = new Object[strValues.length];
119 for (int i=0;i<values.length; i++) values[i] = choiceFrom(strValues[i]);
120 return values;
121 }
122
123 /***
124 * Method asDelimitedString.
125 * @param value Object
126 * @return String
127 * @see net.sourceforge.pmd.PropertyDescriptor#asDelimitedString(Object)
128 */
129 public String asDelimitedString(Object value) {
130
131 if (maxValueCount() == 1) return (String)labelsByChoice.get(value);
132
133 Object[] choices = (Object[])value;
134
135 StringBuffer sb = new StringBuffer();
136
137 sb.append(labelsByChoice.get(choices[0]));
138
139 for (int i=1; i<choices.length; i++) {
140 sb.append(multiValueDelimiter);
141 sb.append(labelsByChoice.get(choices[i]));
142 }
143
144 return sb.toString();
145 }
146 }