ImmutableReceiverChainResolutionStrategy implements IResolveDependencyStrategy { @Override public <T> T resolve(final Object... args) throws ResolveDependencyStrategyException { try { Object chainId = args[CHAIN_ID_ARG_INDEX]; IObject description = (IObject) args[DESCRIPTION_ARG_INDEX]; IChainStorage chainStorage = (IChainStorage) args[STORAGE_ARG_INDEX]; IRouter router = (IRouter) args[ROUTER_ARG_INDEX]; IKey fieldNameKey = Keys.getOrAdd("info.smart_tools.smartactors.iobject.ifield_name.IFieldName"); IKey receiverIdKey = Keys.getOrAdd("receiver_id_from_iobject"); IKey chainIdKey = Keys.getOrAdd("chain_id"); IFieldName stepsFieldName = IOC.resolve(fieldNameKey, "steps"); IFieldName exceptionalChainsFieldName = IOC.resolve(fieldNameKey, "exceptional"); IFieldName exceptionClassFieldName = IOC.resolve(fieldNameKey, "class"); IFieldName exceptionChainFieldName = IOC.resolve(fieldNameKey, "chain"); IFieldName exceptionAfterFieldName = IOC.resolve(fieldNameKey, "after"); List chainSteps = (List) description.getValue(stepsFieldName); List exceptionalChains = (List) description.getValue(exceptionalChainsFieldName); IMessageReceiver[] receivers = new IMessageReceiver[chainSteps.size()]; IObject[] arguments = new IObject[chainSteps.size()]; for (int i = 0; i < chainSteps.size(); i++) { IObject step = (IObject) chainSteps.get(i); receivers[i] = router.route(IOC.resolve(receiverIdKey, step)); arguments[i] = step; } LinkedHashMap<Class<? extends Throwable>, IObject> exceptionalChainsMap = new LinkedHashMap<>(); for (Object chainDesc : exceptionalChains) { IObject desc = (IObject) chainDesc; Class<?> clazz = this.getClass().getClassLoader().loadClass(String.valueOf(desc.getValue(exceptionClassFieldName))); IReceiverChain chain = chainStorage.resolve(IOC.resolve(chainIdKey, desc.getValue(exceptionChainFieldName))); IAction<IMessageProcessingSequence> afterExceptionAction = IOC.resolve( IOC.resolve(IOC.getKeyForKeyStorage(), "afterExceptionAction#" + desc.getValue(exceptionAfterFieldName)) ); IObject chainAndEnv = IOC.resolve(IOC.resolve(IOC.getKeyForKeyStorage(), "info.smart_tools.smartactors.iobject.iobject.IObject")); chainAndEnv.setValue(exceptionChainFieldName, chain); chainAndEnv.setValue(exceptionAfterFieldName, afterExceptionAction); exceptionalChainsMap.put((Class<? extends Throwable>) clazz, chainAndEnv); } return (T) new ImmutableReceiverChain(String.valueOf(chainId), description, receivers, arguments, exceptionalChainsMap); } catch (ChainNotFoundException | ClassNotFoundException | ResolutionException | ReadValueException | RouteNotFoundException | ChangeValueException | InvalidArgumentException e) { throw new ResolveDependencyStrategyException(e); } }  @Override T resolve(final Object... args);  }
@Test public void Should_createImmutableReceiverChains() throws Exception { IObject description = mock(IObject.class); List<IObject> steps = new LinkedList<>(); List<IObject> exceptionals = new LinkedList<>(); Object chainId = "chain"; IReceiverChain exceptionalChain1 = mock(IReceiverChain.class); IReceiverChain exceptionalChain2 = mock(IReceiverChain.class); IMessageReceiver receiver1 = mock(IMessageReceiver.class); IMessageReceiver receiver2 = mock(IMessageReceiver.class); IObject step1 = mock(IObject.class); IObject step2 = mock(IObject.class); when(description.getValue(same(IOC.resolve(fieldNameKey, "steps")))).thenReturn(steps); when(description.getValue(same(IOC.resolve(fieldNameKey, "exceptional")))).thenReturn(exceptionals); steps.add(step1); steps.add(step2); IObject exceptional1 = mock(IObject.class); when(exceptional1.getValue(same(IOC.resolve(fieldNameKey, "class")))).thenReturn(Exception.class.getCanonicalName()); when(exceptional1.getValue(same(IOC.resolve(fieldNameKey, "chain")))).thenReturn("ex_ch1"); IObject exceptional2 = mock(IObject.class); when(exceptional2.getValue(same(IOC.resolve(fieldNameKey, "class")))).thenReturn(Error.class.getCanonicalName()); when(exceptional2.getValue(same(IOC.resolve(fieldNameKey, "chain")))).thenReturn("ex_ch2"); when(chainStorageMock.resolve("ex_ch_1id")).thenReturn(exceptionalChain1); when(chainStorageMock.resolve("ex_ch_2id")).thenReturn(exceptionalChain2); exceptionals.add(exceptional1); exceptionals.add(exceptional2); when(IOC.resolve(same(chainIdKey), eq("ex_ch1"))).thenReturn("ex_ch_1id"); when(IOC.resolve(same(chainIdKey), eq("ex_ch2"))).thenReturn("ex_ch_2id"); when(IOC.resolve(same(receiverIdKey), same(step1))).thenReturn("rec1"); when(IOC.resolve(same(receiverIdKey), same(step2))).thenReturn("rec2"); when(routerMock.route("rec1")).thenReturn(receiver1); when(routerMock.route("rec2")).thenReturn(receiver2); IReceiverChain chain = new ImmutableReceiverChainResolutionStrategy().resolve(chainId, description, chainStorageMock, routerMock); assertNotNull(chain); }
@Test(expected = ResolveDependencyStrategyException.class) public void Should_wrapExceptions() throws Exception { IObject description = mock(IObject.class); when(description.getValue(any())).thenThrow(ReadValueException.class); new ImmutableReceiverChainResolutionStrategy() .resolve("chain", description, chainStorageMock, routerMock); }