1 package org.kohsuke.args4j;
2
3 import org.kohsuke.args4j.spi.Setter;
4
5 import java.lang.reflect.Field;
6 import java.lang.reflect.ParameterizedType;
7 import java.lang.reflect.Type;
8 import java.util.ArrayList;
9 import java.util.List;
10
11 /***
12 * {@link Setter} that sets multiple values to a collection {@link Field}.
13 *
14 * @author Kohsuke Kawaguchi
15 */
16 final class MultiValueFieldSetter implements Setter {
17 private final Object bean;
18 private final Field f;
19
20 public MultiValueFieldSetter(Object bean, Field f) {
21 this.bean = bean;
22 this.f = f;
23
24 if(!List.class.isAssignableFrom(f.getType()))
25 throw new IllegalAnnotationError(Messages.ILLEGAL_FIELD_SIGNATURE.format(f.getType()));
26 }
27
28 public Class getType() {
29
30 Type t = f.getGenericType();
31 if(t instanceof ParameterizedType) {
32 ParameterizedType pt = (ParameterizedType)t;
33 t = pt.getActualTypeArguments()[0];
34 if(t instanceof Class)
35 return (Class)t;
36 }
37 return Object.class;
38 }
39
40 public void addValue(Object value) {
41 try {
42 doAddValue(bean, value);
43 } catch (IllegalAccessException _) {
44
45 f.setAccessible(true);
46 try {
47 doAddValue(bean,value);
48 } catch (IllegalAccessException e) {
49 throw new IllegalAccessError(e.getMessage());
50 }
51 }
52 }
53
54 private void doAddValue(Object bean, Object value) throws IllegalAccessException {
55 Object o = f.get(bean);
56 if(o==null) {
57 o = new ArrayList();
58 f.set(bean,o);
59 }
60 if(!(o instanceof List))
61 throw new IllegalAnnotationError("type of "+f+" is not a List");
62
63 ((List)o).add(value);
64 }
65 }