View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.rule.properties;
5   
6   import java.util.Map;
7   
8   import net.sourceforge.pmd.PropertyDescriptorFactory;
9   import net.sourceforge.pmd.lang.rule.properties.factories.BasicPropertyDescriptorFactory;
10  import net.sourceforge.pmd.util.StringUtil;
11  
12  /**
13   * Defines a datatype that supports multiple String values.
14   * Note that all strings must be filtered by the delimiter character.
15   * 
16   * @author Brian Remedios
17   */
18  public class StringMultiProperty extends AbstractDelimitedProperty<String[]> {
19  		
20  	public static final char DEFAULT_DELIMITER = '|';
21  		
22  	public static final PropertyDescriptorFactory FACTORY = new BasicPropertyDescriptorFactory<StringMultiProperty>(String[].class) {
23  
24  		public StringMultiProperty createWith(Map<String, String> valuesById) {
25  			final char delimiter = delimiterIn(valuesById);
26  			return new StringMultiProperty(
27  					nameIn(valuesById),
28  					descriptionIn(valuesById),
29  					StringUtil.substringsOf(defaultValueIn(valuesById), delimiter),
30  					0f,
31  					delimiter
32  					);
33  		}
34  	};
35  	
36  	/**
37  	 * Constructor for StringProperty.
38  	 * @param theName String
39  	 * @param theDescription String
40  	 * @param theDefaults String[]
41  	 * @param theUIOrder float
42  	 * @param delimiter String
43  	 * @throws IllegalArgumentException
44  	 */
45  	public StringMultiProperty(String theName, String theDescription, String[] theDefaults, float theUIOrder, char delimiter) {
46  		super(theName, theDescription, theDefaults, delimiter, theUIOrder);
47  
48  		checkDefaults(theDefaults, delimiter);
49  	}
50  	
51  	/**
52       * Constructor for CharacterProperty that accepts additional params from a map.
53       * 
54  	 * @param theName
55  	 * @param theDescription
56  	 * @param theDefaults
57  	 * @param otherParams
58  	 */
59  	public StringMultiProperty(String theName, String theDescription, String theDefaults, Map<String, String> otherParams) {
60  	    this(theName, theDescription, StringUtil.substringsOf(theDefaults, delimiterIn(otherParams)), 0.0f, delimiterIn(otherParams));
61  	}
62  	
63  	/**
64  	 * @param defaultValue
65  	 * @param delim
66  	 * @throws IllegalArgumentException
67  	 */
68  	private static void checkDefaults(String[] defaultValue, char delim) {
69  		
70  		if (defaultValue == null) { return;	}
71  		
72  		for (int i=0; i<defaultValue.length; i++) {
73  			if (defaultValue[i].indexOf(delim) >= 0) {
74  				throw new IllegalArgumentException("Cannot include the delimiter in the set of defaults");
75  			}
76  		}
77  	}
78  	
79  	/**
80  	 * @return Class
81  	 * @see net.sourceforge.pmd.PropertyDescriptor#type()
82  	 */
83  	public Class<String[]> type() {
84  		return String[].class;
85  	}
86  	
87  	/**
88  	 * @param valueString String
89  	 * @return Object
90  	 * @see net.sourceforge.pmd.PropertyDescriptor#valueFrom(String)
91  	 */
92  	public String[] valueFrom(String valueString) {
93  		return StringUtil.substringsOf(valueString, multiValueDelimiter());
94  	}
95  	
96  	/**
97  	 * @param value String
98  	 * @return boolean
99  	 */
100 	private boolean containsDelimiter(String value) {
101 		return value.indexOf(multiValueDelimiter()) >= 0;
102 	}
103 	
104 	/**
105 	 * @return String
106 	 */
107 	private final String illegalCharMsg() {
108 		return "Value cannot contain the '" + multiValueDelimiter() + "' character";
109 	}
110 	
111 	/**
112 	 * 
113 	 * @param value Object
114 	 * @return String
115 	 */
116 	protected String valueErrorFor(Object value) {
117 
118 		if (value==null) { return "missing value"; }
119 		
120 		String testValue = (String)value;
121 		if (containsDelimiter(testValue)) {
122 		    return illegalCharMsg();			
123 		}
124 		
125 		// TODO - eval against regex checkers
126 		
127 		return null;		
128 	}
129 }