private TypedMember(Method method, Object scope, CommandSpec spec) { accessible = Assert.notNull(method, "method"); accessible.setAccessible(true); name = propertyName(method.getName()); Class<?>[] parameterTypes = method.getParameterTypes(); boolean isGetter = parameterTypes.length == 0 && method.getReturnType() != Void.TYPE && method.getReturnType() != Void.class; boolean isSetter = parameterTypes.length > 0; if (isSetter == isGetter) { throw new InitializationException("Invalid method, must be either getter or setter: " + method); } if (isGetter) { hasInitialValue = true; typeInfo = createTypeInfo(method.getReturnType(), method.getGenericReturnType()); if (Proxy.isProxyClass(scope.getClass())) { PicocliInvocationHandler handler = (PicocliInvocationHandler) Proxy.getInvocationHandler(scope); PicocliInvocationHandler.ProxyBinding binding = handler.new ProxyBinding(method); getter = binding; setter = binding; initializeInitialValue(method); } else { //throw new IllegalArgumentException("Getter method but not a proxy: " + scope + ": " + method); MethodBinding binding = new MethodBinding(scope, method, spec); getter = binding; setter = binding; } } else { hasInitialValue = false; typeInfo = createTypeInfo(parameterTypes[0], method.getGenericParameterTypes()[0]); MethodBinding binding = new MethodBinding(scope, method, spec); getter = binding; setter = binding; } } private TypedMember(MethodParam param, Object scope) {
public <T> T set(T value) throws PicocliException { try { @SuppressWarnings("unchecked") T result = (T) currentValue; method.invoke(scope, value); currentValue = value; return result; } catch (InvocationTargetException ex) { if (ex.getCause() instanceof PicocliException) { throw (PicocliException) ex.getCause(); } throw createParameterException(value, ex.getCause()); } catch (Exception ex) { throw createParameterException(value, ex); } } private ParameterException createParameterException(Object value, Throwable t) {
@Test public void testGetReturnsNullForGetterMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); getX.setAccessible(true); ModelMethodBindingBean bean = new ModelMethodBindingBean(); MethodBinding binding = new MethodBinding(bean, getX, CommandSpec.create()); assertNull(binding.get()); assertEquals("actual value returned by getX() method", 7, bean.publicGetX()); }
} else { MethodBinding binding = new MethodBinding(scope, method, spec); getter = binding; setter = binding; type = parameterTypes[0]; genericType = method.getGenericParameterTypes()[0]; MethodBinding binding = new MethodBinding(scope, method, spec); getter = binding; setter = binding;
@Test public void testExceptionHandlingCreatesCommandLineIfNecessary() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); assertNull(spec.commandLine()); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { assertNotNull(spec.commandLine()); // has been set ParameterException pex = (ParameterException) ex; assertSame(pex.getCommandLine(), spec.commandLine()); assertSame(spec, pex.getCommandLine().getCommandSpec()); } } }
@Test public void testSetInvokesMethod_FailsForGetterMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); getX.setAccessible(true); ModelMethodBindingBean bean = new ModelMethodBindingBean(); CommandSpec spec = CommandSpec.create(); MethodBinding binding = new MethodBinding(bean, getX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(spec, pex.getCommandLine().getCommandSpec()); assertThat(pex.getCause().getClass().toString(), pex.getCause() instanceof IllegalArgumentException); assertEquals("wrong number of arguments", pex.getCause().getMessage()); } }
@Test public void testExceptionHandlingUsesCommandLineIfAvailable() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); CommandLine cmd = new CommandLine(spec); spec.commandLine(cmd); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(cmd, pex.getCommandLine()); } }
public <T> T set(T value) throws PicocliException { try { @SuppressWarnings("unchecked") T result = (T) currentValue; method.invoke(scope, value); currentValue = value; return result; } catch (InvocationTargetException ex) { if (ex.getCause() instanceof PicocliException) { throw (PicocliException) ex.getCause(); } throw createParameterException(value, ex.getCause()); } catch (Exception ex) { throw createParameterException(value, ex); } } private ParameterException createParameterException(Object value, Throwable t) {
@Test public void testSetFailsIfObjectNotSet_ForSetterMethod() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(spec, pex.getCommandLine().getCommandSpec()); assertThat(pex.getCause().getClass().toString(), pex.getCause() instanceof NullPointerException); } }
@Test public void testGetDoesNotInvokeMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); MethodBinding binding = new MethodBinding(new ModelMethodBindingBean(), getX, CommandSpec.create()); binding.get(); // no IllegalAccessException }
@Test public void testGetReturnsLastSetValue_ForSetterMethod() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); ModelMethodBindingBean bean = new ModelMethodBindingBean(); MethodBinding binding = new MethodBinding(bean, setX, CommandSpec.create()); assertNull("initial", binding.get()); assertEquals(7, bean.publicGetX()); binding.set(41); assertEquals(41, bean.publicGetX()); assertEquals(41, binding.get()); }
@Test public void testMethodMustBeAccessible() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); MethodBinding binding = new MethodBinding(new ModelMethodBindingBean(), setX, CommandSpec.create()); try { binding.set(1); fail("Expected exception"); } catch (PicocliException ok) { assertThat("not accessible", ok.getCause() instanceof IllegalAccessException); } }
@Test public void testGetReturnsNullForGetterMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); getX.setAccessible(true); ModelMethodBindingBean bean = new ModelMethodBindingBean(); MethodBinding binding = new MethodBinding(bean, getX, CommandSpec.create()); assertNull(binding.get()); assertEquals("actual value returned by getX() method", 7, bean.publicGetX()); }
@Test public void testSetInvokesMethod_ForSetterMethod() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); ModelMethodBindingBean value = new ModelMethodBindingBean(); MethodBinding binding = new MethodBinding(value, setX, CommandSpec.create()); binding.set(987); assertEquals(987, value.publicGetX()); assertEquals(987, binding.get()); }
@Test public void testExceptionHandlingCreatesCommandLineIfNecessary() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); assertNull(spec.commandLine()); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { assertNotNull(spec.commandLine()); // has been set ParameterException pex = (ParameterException) ex; assertSame(pex.getCommandLine(), spec.commandLine()); assertSame(spec, pex.getCommandLine().getCommandSpec()); } } }
@Test public void testSetInvokesMethod_FailsForGetterMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); getX.setAccessible(true); ModelMethodBindingBean bean = new ModelMethodBindingBean(); CommandSpec spec = CommandSpec.create(); MethodBinding binding = new MethodBinding(bean, getX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(spec, pex.getCommandLine().getCommandSpec()); assertThat(pex.getCause().getClass().toString(), pex.getCause() instanceof IllegalArgumentException); assertEquals("wrong number of arguments", pex.getCause().getMessage()); } }
@Test public void testExceptionHandlingUsesCommandLineIfAvailable() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); CommandLine cmd = new CommandLine(spec); spec.commandLine(cmd); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(cmd, pex.getCommandLine()); } }
@Test public void testSetFailsIfObjectNotSet_ForSetterMethod() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); setX.setAccessible(true); CommandSpec spec = CommandSpec.create(); MethodBinding binding = new MethodBinding(null, setX, spec); try { binding.set(41); fail("Expect exception"); } catch (Exception ex) { ParameterException pex = (ParameterException) ex; assertSame(spec, pex.getCommandLine().getCommandSpec()); assertThat(pex.getCause().getClass().toString(), pex.getCause() instanceof NullPointerException); } }
@Test public void testGetDoesNotInvokeMethod() throws Exception { Method getX = ModelMethodBindingBean.class.getDeclaredMethod("getX"); MethodBinding binding = new MethodBinding(new ModelMethodBindingBean(), getX, CommandSpec.create()); binding.get(); // no IllegalAccessException }
@Test public void testMethodMustBeAccessible() throws Exception { Method setX = ModelMethodBindingBean.class.getDeclaredMethod("setX", int.class); MethodBinding binding = new MethodBinding(new ModelMethodBindingBean(), setX, CommandSpec.create()); try { binding.set(1); fail("Expected exception"); } catch (PicocliException ok) { assertThat("not accessible", ok.getCause() instanceof IllegalAccessException); } }