View Javadoc

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 }