• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.beust.jcommander;
2 
3 import com.beust.jcommander.internal.Lists;
4 
5 import java.lang.annotation.Annotation;
6 import java.lang.reflect.Field;
7 import java.lang.reflect.InvocationTargetException;
8 import java.lang.reflect.Method;
9 import java.lang.reflect.ParameterizedType;
10 import java.lang.reflect.Type;
11 import java.util.List;
12 
13 /**
14  * Encapsulate a field or a method annotated with @Parameter or @DynamicParameter
15  */
16 public class Parameterized {
17 
18   // Either a method or a field
19   private Field m_field;
20   private Method m_method;
21   private Method m_getter;
22 
23   // Either of these two
24   private WrappedParameter m_wrappedParameter;
25   private ParametersDelegate m_parametersDelegate;
26 
Parameterized(WrappedParameter wp, ParametersDelegate pd, Field field, Method method)27   public Parameterized(WrappedParameter wp, ParametersDelegate pd,
28       Field field, Method method) {
29     m_wrappedParameter = wp;
30     m_method = method;
31     m_field = field;
32     if (m_field != null) {
33       m_field.setAccessible(true);
34     }
35     m_parametersDelegate = pd;
36   }
37 
parseArg(Object arg)38   public static List<Parameterized> parseArg(Object arg) {
39     List<Parameterized> result = Lists.newArrayList();
40 
41     Class<? extends Object> cls = arg.getClass();
42     while (!Object.class.equals(cls)) {
43       for (Field f : cls.getDeclaredFields()) {
44         Annotation annotation = f.getAnnotation(Parameter.class);
45         Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class);
46         Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class);
47         if (annotation != null) {
48           result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null,
49               f, null));
50         } else if (dynamicParameter != null) {
51           result.add(new Parameterized(new WrappedParameter((DynamicParameter) dynamicParameter), null,
52               f, null));
53         } else if (delegateAnnotation != null) {
54           result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation,
55               f, null));
56         }
57       }
58       cls = cls.getSuperclass();
59     }
60 
61     // Reassigning
62     cls = arg.getClass();
63     while (!Object.class.equals(cls)) {
64       for (Method m : cls.getDeclaredMethods()) {
65         Annotation annotation = m.getAnnotation(Parameter.class);
66         Annotation delegateAnnotation = m.getAnnotation(ParametersDelegate.class);
67         Annotation dynamicParameter = m.getAnnotation(DynamicParameter.class);
68         if (annotation != null) {
69           result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null,
70               null, m));
71         } else if (dynamicParameter != null) {
72           result.add(new Parameterized(new WrappedParameter((DynamicParameter) annotation), null,
73               null, m));
74         } else if (delegateAnnotation != null) {
75           result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation,
76               null, m));
77         }
78       }
79       cls = cls.getSuperclass();
80     }
81 
82     return result;
83   }
84 
getWrappedParameter()85   public WrappedParameter getWrappedParameter() {
86     return m_wrappedParameter;
87   }
88 
getType()89   public Class<?> getType() {
90     if (m_method != null) {
91       return m_method.getParameterTypes()[0];
92     } else {
93       return m_field.getType();
94     }
95   }
96 
getName()97   public String getName() {
98     if (m_method != null) {
99       return m_method.getName();
100     } else {
101       return m_field.getName();
102     }
103   }
104 
get(Object object)105   public Object get(Object object) {
106     try {
107       if (m_method != null) {
108         if (m_getter == null) {
109             m_getter = m_method.getDeclaringClass()
110                 .getMethod("g" + m_method.getName().substring(1),
111                 new Class[0]);
112         }
113         return m_getter.invoke(object);
114       } else {
115         return m_field.get(object);
116       }
117     } catch (SecurityException e) {
118       throw new ParameterException(e);
119     } catch (NoSuchMethodException e) {
120       // Try to find a field
121       String name = m_method.getName();
122       String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
123       Object result = null;
124       try {
125         Field field = m_method.getDeclaringClass().getDeclaredField(fieldName);
126         if (field != null) {
127           field.setAccessible(true);
128           result = field.get(object);
129         }
130       } catch(NoSuchFieldException ex) {
131         // ignore
132       } catch(IllegalAccessException ex) {
133         // ignore
134       }
135       return result;
136     } catch (IllegalArgumentException e) {
137       throw new ParameterException(e);
138     } catch (IllegalAccessException e) {
139       throw new ParameterException(e);
140     } catch (InvocationTargetException e) {
141       throw new ParameterException(e);
142     }
143   }
144 
145   @Override
hashCode()146   public int hashCode() {
147     final int prime = 31;
148     int result = 1;
149     result = prime * result + ((m_field == null) ? 0 : m_field.hashCode());
150     result = prime * result + ((m_method == null) ? 0 : m_method.hashCode());
151     return result;
152   }
153 
154   @Override
equals(Object obj)155   public boolean equals(Object obj) {
156     if (this == obj)
157       return true;
158     if (obj == null)
159       return false;
160     if (getClass() != obj.getClass())
161       return false;
162     Parameterized other = (Parameterized) obj;
163     if (m_field == null) {
164       if (other.m_field != null)
165         return false;
166     } else if (!m_field.equals(other.m_field))
167       return false;
168     if (m_method == null) {
169       if (other.m_method != null)
170         return false;
171     } else if (!m_method.equals(other.m_method))
172       return false;
173     return true;
174   }
175 
isDynamicParameter(Field field)176   public boolean isDynamicParameter(Field field) {
177     if (m_method != null) {
178       return m_method.getAnnotation(DynamicParameter.class) != null;
179     } else {
180       return m_field.getAnnotation(DynamicParameter.class) != null;
181     }
182   }
183 
set(Object object, Object value)184   public void set(Object object, Object value) {
185     try {
186       if (m_method != null) {
187         m_method.invoke(object, value);
188       } else {
189           m_field.set(object, value);
190       }
191     } catch (IllegalArgumentException ex) {
192       throw new ParameterException(ex);
193     } catch (IllegalAccessException ex) {
194       throw new ParameterException(ex);
195     } catch (InvocationTargetException ex) {
196       // If a ParameterException was thrown, don't wrap it into another one
197       if (ex.getTargetException() instanceof ParameterException) {
198         throw (ParameterException) ex.getTargetException();
199       } else {
200         throw new ParameterException(ex);
201       }
202     }
203   }
204 
getDelegateAnnotation()205   public ParametersDelegate getDelegateAnnotation() {
206     return m_parametersDelegate;
207   }
208 
getGenericType()209   public Type getGenericType() {
210     if (m_method != null) {
211       return m_method.getGenericParameterTypes()[0];
212     } else {
213       return m_field.getGenericType();
214     }
215   }
216 
getParameter()217   public Parameter getParameter() {
218     return m_wrappedParameter.getParameter();
219   }
220 
221   /**
222    * @return the generic type of the collection for this field, or null if not applicable.
223    */
findFieldGenericType()224   public Type findFieldGenericType() {
225     if (m_method != null) {
226       return null;
227     } else {
228       if (m_field.getGenericType() instanceof ParameterizedType) {
229         ParameterizedType p = (ParameterizedType) m_field.getGenericType();
230         Type cls = p.getActualTypeArguments()[0];
231         if (cls instanceof Class) {
232           return cls;
233         }
234       }
235     }
236 
237     return null;
238   }
239 
isDynamicParameter()240   public boolean isDynamicParameter() {
241     return m_wrappedParameter.getDynamicParameter() != null;
242   }
243 
244 }
245