DataOperationInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) { log.info("A method call to " + method + " has been intercepted. We will now try to find an appropriate invocation."); final Invocation methodInvocation = new ImmutableInvocation(method, args); InvocationMapping<K, E> targetMapping = null; if (!misses.contains(method)) { if (cache.containsKey(method)) { targetMapping = cache.get(method); } else { for (InvocationMapping<K, E> mapping : mappings) { if (mapping.getMethod().equals(method)) { targetMapping = mapping; cache.put(method, targetMapping); break; } } } } if (targetMapping == null) { log.info( "The invocation cannot be resolved using a data operation. We will try to handle this as a " + "non-data operation"); misses.add(method); return operationInvocationHandler.invoke(proxy, method, args); } final DataStoreOperation<?, K, E> operation = targetMapping.getOperation(); log.info("Executing the operation for method " + method); final Object operationResult = operation.execute(dataStore, repositoryConfiguration, methodInvocation); log.info("Trying to see if any conversion is necessary on the object"); final Object convertedResult = converter.convert(methodInvocation, operationResult); return adapterContext.adapt(methodInvocation, convertedResult); } DataOperationInvocationHandler(RepositoryConfiguration repositoryConfiguration,
                                          List<InvocationMapping<K, E>> mappings,
                                          DataStore<K, E> dataStore, ResultAdapterContext adapterContext,
                                          NonDataOperationInvocationHandler operationInvocationHandler); @Override Object invoke(Object proxy, Method method, Object[] args);  }
@Test public void testCallingHashCode() throws Throwable { final Object proxy = new Object(); final Object result = handler.invoke(proxy, Object.class.getMethod("hashCode"), new Object[]{}); assertThat(result, is(notNullValue())); assertThat(result, is(proxy.hashCode())); }
@Test public void testCallingEqualsWhenTheyAreIdentical() throws Throwable { final Object proxy = new Object(); final Object result = handler.invoke(proxy, Object.class.getMethod("equals", Object.class), new Object[]{proxy}); assertThat(result, is(notNullValue())); assertThat(result, is(instanceOf(Boolean.class))); assertThat(result, is(true)); }
@Test public void testCallingEqualsWhenTheyAreNotIdentical() throws Throwable { final Object proxy = new Object(); final Object result = handler.invoke(proxy, Object.class.getMethod("equals", Object.class), new Object[]{new Object()}); assertThat(result, is(notNullValue())); assertThat(result, is(false)); }
@Test public void testCallingToString() throws Throwable { final Object proxy = new Object(); final Object result = handler.invoke(proxy, Object.class.getMethod("toString"), new Object[]{}); assertThat(result, is(notNullValue())); assertThat(result, is(proxy.toString())); }
@Test public void testMissingMethodTwice() throws Throwable { assertThat(handler.invoke(new Object(), Object.class.getMethod("toString"), new Object[]{}), is(notNullValue())); assertThat(handler.invoke(new Object(), Object.class.getMethod("toString"), new Object[]{}), is(notNullValue())); }
@Test public void testInvokingBoundMapping() throws Throwable { final Object originalValue = new Object(); final SpyingOperation spy = new SpyingOperation(originalValue); mappings.add(new ImmutableInvocationMapping<>(ReturnTypeSampleRepository.class.getMethod("findOther"), spy)); final Object[] args = {1, 2, 3}; final Object result = handler.invoke(new Object(), ReturnTypeSampleRepository.class.getMethod("findOther"), args); assertThat(spy.getInvocation(), is(notNullValue())); assertThat(spy.getInvocation().getMethod(), is(ReturnTypeSampleRepository.class.getMethod("findOther"))); assertThat(spy.getInvocation().getArguments(), is(args)); assertThat(result, is(originalValue)); }
@Test public void testInvokingBoundMappingTwice() throws Throwable { final Object originalValue = new Object(); final SpyingOperation spy = new SpyingOperation(originalValue); final SpyingOperation otherSpy = new SpyingOperation(originalValue); mappings.add(new ImmutableInvocationMapping<>(Object.class.getMethod("hashCode"), otherSpy)); mappings.add(new ImmutableInvocationMapping<>(ReturnTypeSampleRepository.class.getMethod("findOther"), spy)); assertThat(handler.invoke(new Object(), ReturnTypeSampleRepository.class.getMethod("findOther"), new Object[]{1, 2, 3}), is(originalValue)); assertThat(handler.invoke(new Object(), ReturnTypeSampleRepository.class.getMethod("findOther"), new Object[]{4, 5, 6}), is(originalValue)); assertThat(otherSpy.getInvocation(), is(nullValue())); }