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 }