summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/beust/jcommander/Parameterized.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/beust/jcommander/Parameterized.java')
-rw-r--r--src/main/java/com/beust/jcommander/Parameterized.java244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/main/java/com/beust/jcommander/Parameterized.java b/src/main/java/com/beust/jcommander/Parameterized.java
new file mode 100644
index 0000000..ff8753b
--- /dev/null
+++ b/src/main/java/com/beust/jcommander/Parameterized.java
@@ -0,0 +1,244 @@
+package com.beust.jcommander;
+
+import com.beust.jcommander.internal.Lists;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+/**
+ * Encapsulate a field or a method annotated with @Parameter or @DynamicParameter
+ */
+public class Parameterized {
+
+ // Either a method or a field
+ private Field m_field;
+ private Method m_method;
+ private Method m_getter;
+
+ // Either of these two
+ private WrappedParameter m_wrappedParameter;
+ private ParametersDelegate m_parametersDelegate;
+
+ public Parameterized(WrappedParameter wp, ParametersDelegate pd,
+ Field field, Method method) {
+ m_wrappedParameter = wp;
+ m_method = method;
+ m_field = field;
+ if (m_field != null) {
+ m_field.setAccessible(true);
+ }
+ m_parametersDelegate = pd;
+ }
+
+ public static List<Parameterized> parseArg(Object arg) {
+ List<Parameterized> result = Lists.newArrayList();
+
+ Class<? extends Object> cls = arg.getClass();
+ while (!Object.class.equals(cls)) {
+ for (Field f : cls.getDeclaredFields()) {
+ Annotation annotation = f.getAnnotation(Parameter.class);
+ Annotation delegateAnnotation = f.getAnnotation(ParametersDelegate.class);
+ Annotation dynamicParameter = f.getAnnotation(DynamicParameter.class);
+ if (annotation != null) {
+ result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null,
+ f, null));
+ } else if (dynamicParameter != null) {
+ result.add(new Parameterized(new WrappedParameter((DynamicParameter) dynamicParameter), null,
+ f, null));
+ } else if (delegateAnnotation != null) {
+ result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation,
+ f, null));
+ }
+ }
+ cls = cls.getSuperclass();
+ }
+
+ // Reassigning
+ cls = arg.getClass();
+ while (!Object.class.equals(cls)) {
+ for (Method m : cls.getDeclaredMethods()) {
+ Annotation annotation = m.getAnnotation(Parameter.class);
+ Annotation delegateAnnotation = m.getAnnotation(ParametersDelegate.class);
+ Annotation dynamicParameter = m.getAnnotation(DynamicParameter.class);
+ if (annotation != null) {
+ result.add(new Parameterized(new WrappedParameter((Parameter) annotation), null,
+ null, m));
+ } else if (dynamicParameter != null) {
+ result.add(new Parameterized(new WrappedParameter((DynamicParameter) annotation), null,
+ null, m));
+ } else if (delegateAnnotation != null) {
+ result.add(new Parameterized(null, (ParametersDelegate) delegateAnnotation,
+ null, m));
+ }
+ }
+ cls = cls.getSuperclass();
+ }
+
+ return result;
+ }
+
+ public WrappedParameter getWrappedParameter() {
+ return m_wrappedParameter;
+ }
+
+ public Class<?> getType() {
+ if (m_method != null) {
+ return m_method.getParameterTypes()[0];
+ } else {
+ return m_field.getType();
+ }
+ }
+
+ public String getName() {
+ if (m_method != null) {
+ return m_method.getName();
+ } else {
+ return m_field.getName();
+ }
+ }
+
+ public Object get(Object object) {
+ try {
+ if (m_method != null) {
+ if (m_getter == null) {
+ m_getter = m_method.getDeclaringClass()
+ .getMethod("g" + m_method.getName().substring(1),
+ new Class[0]);
+ }
+ return m_getter.invoke(object);
+ } else {
+ return m_field.get(object);
+ }
+ } catch (SecurityException e) {
+ throw new ParameterException(e);
+ } catch (NoSuchMethodException e) {
+ // Try to find a field
+ String name = m_method.getName();
+ String fieldName = Character.toLowerCase(name.charAt(3)) + name.substring(4);
+ Object result = null;
+ try {
+ Field field = m_method.getDeclaringClass().getDeclaredField(fieldName);
+ if (field != null) {
+ field.setAccessible(true);
+ result = field.get(object);
+ }
+ } catch(NoSuchFieldException ex) {
+ // ignore
+ } catch(IllegalAccessException ex) {
+ // ignore
+ }
+ return result;
+ } catch (IllegalArgumentException e) {
+ throw new ParameterException(e);
+ } catch (IllegalAccessException e) {
+ throw new ParameterException(e);
+ } catch (InvocationTargetException e) {
+ throw new ParameterException(e);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((m_field == null) ? 0 : m_field.hashCode());
+ result = prime * result + ((m_method == null) ? 0 : m_method.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Parameterized other = (Parameterized) obj;
+ if (m_field == null) {
+ if (other.m_field != null)
+ return false;
+ } else if (!m_field.equals(other.m_field))
+ return false;
+ if (m_method == null) {
+ if (other.m_method != null)
+ return false;
+ } else if (!m_method.equals(other.m_method))
+ return false;
+ return true;
+ }
+
+ public boolean isDynamicParameter(Field field) {
+ if (m_method != null) {
+ return m_method.getAnnotation(DynamicParameter.class) != null;
+ } else {
+ return m_field.getAnnotation(DynamicParameter.class) != null;
+ }
+ }
+
+ public void set(Object object, Object value) {
+ try {
+ if (m_method != null) {
+ m_method.invoke(object, value);
+ } else {
+ m_field.set(object, value);
+ }
+ } catch (IllegalArgumentException ex) {
+ throw new ParameterException(ex);
+ } catch (IllegalAccessException ex) {
+ throw new ParameterException(ex);
+ } catch (InvocationTargetException ex) {
+ // If a ParameterException was thrown, don't wrap it into another one
+ if (ex.getTargetException() instanceof ParameterException) {
+ throw (ParameterException) ex.getTargetException();
+ } else {
+ throw new ParameterException(ex);
+ }
+ }
+ }
+
+ public ParametersDelegate getDelegateAnnotation() {
+ return m_parametersDelegate;
+ }
+
+ public Type getGenericType() {
+ if (m_method != null) {
+ return m_method.getGenericParameterTypes()[0];
+ } else {
+ return m_field.getGenericType();
+ }
+ }
+
+ public Parameter getParameter() {
+ return m_wrappedParameter.getParameter();
+ }
+
+ /**
+ * @return the generic type of the collection for this field, or null if not applicable.
+ */
+ public Type findFieldGenericType() {
+ if (m_method != null) {
+ return null;
+ } else {
+ if (m_field.getGenericType() instanceof ParameterizedType) {
+ ParameterizedType p = (ParameterizedType) m_field.getGenericType();
+ Type cls = p.getActualTypeArguments()[0];
+ if (cls instanceof Class) {
+ return cls;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public boolean isDynamicParameter() {
+ return m_wrappedParameter.getDynamicParameter() != null;
+ }
+
+}