001: package net.sourceforge.pmd.properties;
002:
003: import net.sourceforge.pmd.PropertyDescriptor;
004: import net.sourceforge.pmd.Rule;
005:
006: /**
007: *
008: * @author Brian Remedios
009: * @version $Revision$
010: */
011: public abstract class AbstractPMDProperty implements PropertyDescriptor {
012:
013: private String name;
014: private String description;
015: private Object defaultValue;
016: private boolean isRequired = false;
017: private int maxValueCount = 1;
018: private float uiOrder;
019:
020: protected char multiValueDelimiter = '|';
021:
022: /**
023: * Constructor for AbstractPMDProperty.
024: * @param theName String
025: * @param theDescription String
026: * @param theDefault Object
027: * @param theUIOrder float
028: */
029: protected AbstractPMDProperty(String theName,
030: String theDescription, Object theDefault, float theUIOrder) {
031: name = theName;
032: description = theDescription;
033: defaultValue = theDefault;
034: uiOrder = theUIOrder;
035: }
036:
037: /**
038: * Method multiValueDelimiter.
039: * @param aDelimiter char
040: */
041: protected void multiValueDelimiter(char aDelimiter) {
042: multiValueDelimiter = aDelimiter;
043: }
044:
045: /**
046: * Method multiValueDelimiter.
047: * @return char
048: * @see net.sourceforge.pmd.PropertyDescriptor#multiValueDelimiter()
049: */
050: public char multiValueDelimiter() {
051: return multiValueDelimiter;
052: }
053:
054: /**
055: * Method name.
056: * @return String
057: * @see net.sourceforge.pmd.PropertyDescriptor#name()
058: */
059: public String name() {
060: return name;
061: }
062:
063: /**
064: * Method description.
065: * @return String
066: * @see net.sourceforge.pmd.PropertyDescriptor#description()
067: */
068: public String description() {
069: return description;
070: }
071:
072: /**
073: *
074: * @return Object
075: * @see net.sourceforge.pmd.PropertyDescriptor#defaultValue()
076: */
077: public Object defaultValue() {
078: return defaultValue;
079: }
080:
081: /**
082: * Method maxValueCount.
083: * @return int
084: * @see net.sourceforge.pmd.PropertyDescriptor#maxValueCount()
085: */
086: public int maxValueCount() {
087: return maxValueCount;
088: }
089:
090: /**
091: * Method maxValueCount.
092: * @param theCount int
093: * @see net.sourceforge.pmd.PropertyDescriptor#maxValueCount()
094: */
095: protected void maxValueCount(int theCount) {
096: maxValueCount = theCount;
097: }
098:
099: /**
100: * Method isRequired.
101: * @return boolean
102: * @see net.sourceforge.pmd.PropertyDescriptor#isRequired()
103: */
104: public boolean isRequired() {
105: return isRequired;
106: }
107:
108: /**
109: * Method uiOrder.
110: * @return float
111: * @see net.sourceforge.pmd.PropertyDescriptor#uiOrder()
112: */
113: public float uiOrder() {
114: return uiOrder;
115: }
116:
117: /**
118: * Return the value as a string that can be easily recognized and parsed
119: * when we see it again.
120: *
121: * @param value Object
122: * @return String
123: */
124: protected String asString(Object value) {
125: return value == null ? "" : value.toString();
126: }
127:
128: /**
129: * Method asDelimitedString.
130: * @param values Object
131: * @return String
132: * @see net.sourceforge.pmd.PropertyDescriptor#asDelimitedString(Object)
133: */
134: public String asDelimitedString(Object values) {
135:
136: if (values == null)
137: return "";
138:
139: if (values instanceof Object[]) {
140: Object[] valueSet = (Object[]) values;
141: if (valueSet.length == 0)
142: return "";
143: if (valueSet.length == 1)
144: return asString(valueSet[0]);
145:
146: StringBuffer sb = new StringBuffer();
147: sb.append(asString(valueSet[0]));
148: for (int i = 1; i < valueSet.length; i++) {
149: sb.append(multiValueDelimiter);
150: sb.append(asString(valueSet[i]));
151: }
152: return sb.toString();
153: }
154:
155: return asString(values);
156: }
157:
158: /**
159: * Method compareTo.
160: * @param otherProperty Object
161: * @return int
162: * @see java.lang.Comparable#compareTo(Object)
163: */
164: public int compareTo(PropertyDescriptor otherProperty) {
165: float otherOrder = otherProperty.uiOrder();
166: return (int) (otherOrder - uiOrder);
167: }
168:
169: /**
170: * Method errorFor.
171: * @param value Object
172: * @return String
173: * @see net.sourceforge.pmd.PropertyDescriptor#errorFor(Object)
174: */
175: public String errorFor(Object value) {
176:
177: String typeError = typeErrorFor(value);
178: if (typeError != null)
179: return typeError;
180: return valueErrorFor(value);
181: }
182:
183: /**
184: * Method valueErrorFor.
185: * @param value Object
186: * @return String
187: */
188: protected String valueErrorFor(Object value) {
189: // override as required
190: return null;
191: }
192:
193: /**
194: * Method isArray.
195: * @param value Object
196: * @return boolean
197: */
198: protected boolean isArray(Object value) {
199: return value != null
200: && value.getClass().getComponentType() != null;
201: }
202:
203: /**
204: * Method typeErrorFor.
205: * @param value Object
206: * @return String
207: */
208: protected String typeErrorFor(Object value) {
209:
210: if (value == null && !isRequired)
211: return null;
212:
213: if (maxValueCount > 1) {
214: if (!isArray(value)) {
215: return "Value is not an array of type: " + type();
216: }
217:
218: Class<?> arrayType = value.getClass().getComponentType();
219: if (arrayType == null
220: || !arrayType.isAssignableFrom(type())) {
221: return "Value is not an array of type: " + type();
222: }
223: return null;
224: }
225:
226: if (!type().isAssignableFrom(value.getClass())) {
227: return value + " is not an instance of " + type();
228: }
229:
230: return null;
231: }
232:
233: /**
234: * Method propertyErrorFor.
235: * @param rule Rule
236: * @return String
237: * @see net.sourceforge.pmd.PropertyDescriptor#propertyErrorFor(Rule)
238: */
239: public String propertyErrorFor(Rule rule) {
240: String strValue = rule.getStringProperty(name());
241: if (strValue == null && !isRequired())
242: return null;
243: Object realValue = valueFrom(strValue);
244: return errorFor(realValue);
245: }
246:
247: /**
248: * Method choices.
249: * @return Object[][]
250: * @see net.sourceforge.pmd.PropertyDescriptor#choices()
251: */
252: public Object[][] choices() {
253: return null;
254: }
255:
256: /**
257: * Method preferredRowCount.
258: * @return int
259: * @see net.sourceforge.pmd.PropertyDescriptor#preferredRowCount()
260: */
261: public int preferredRowCount() {
262: return 1;
263: }
264:
265: /**
266: * Method areEqual.
267: * @param value Object
268: * @param otherValue Object
269: * @return boolean
270: */
271: public static final boolean areEqual(Object value, Object otherValue) {
272: if (value == otherValue)
273: return true;
274: if (value == null)
275: return false;
276: if (otherValue == null)
277: return false;
278:
279: return value.equals(otherValue);
280: }
281: }
|