DefaultScoreResolver implements ScoreResolver<Operation> { @Override public Integer getScore(final Operation operation) { if (null == operation) { return 0; } if (operation instanceof Operations && !(operation instanceof NamedOperation)) { int score = 0; for (final Operation op : ((Operations<?>) operation).getOperations()) { score += getScore(op); } return score; } else { final Class<? extends Operation> opClass = operation.getClass(); if (null == skipResolvingOperation || skipResolvingOperation != operation) { ScoreResolver resolver = scoreResolvers.get(opClass); if (null != resolver) { final DefaultScoreResolver delegateResolver = new DefaultScoreResolver(opScores, scoreResolvers, operation); Integer opScore = resolver.getScore(operation, delegateResolver); if (null != opScore) { return opScore; } } } final List<Class<? extends Operation>> keys = new ArrayList<>(opScores.keySet()); for (int i = keys.size() - 1; i >= 0; i--) { final Class<? extends Operation> key = keys.get(i); if (key.isAssignableFrom(opClass)) { return opScores.get(key); } } } return DEFAULT_OPERATION_SCORE; } DefaultScoreResolver();  DefaultScoreResolver(final Map<Class<? extends Operation>, Integer> opScores);  DefaultScoreResolver(final Map<Class<? extends Operation>, Integer> opScores,
                                final Map<Class<? extends Operation>, ScoreResolver> scoreResolvers);  DefaultScoreResolver(final Map<Class<? extends Operation>, Integer> opScores,
                                final Map<Class<? extends Operation>, ScoreResolver> scoreResolvers,
                                final Operation skipResolvingOperation); @Override Integer getScore(final Operation operation); static final int DEFAULT_OPERATION_SCORE; }
@Test public void shouldGetDefaultScoreWhenNoOperationScores() throws OperationException { final DefaultScoreResolver resolver = new DefaultScoreResolver(new LinkedHashMap<>()); final GetAdjacentIds op1 = mock(GetAdjacentIds.class); final int score = resolver.getScore(op1); assertEquals(1, score); }
@Test public void shouldGetScore() { final GetAdjacentIds op1 = mock(GetAdjacentIds.class); final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(Operation.class, 1); opScores.put(GetAdjacentIds.class, 2); opScores.put(GetElements.class, 1); opScores.put(Limit.class, 1); final DefaultScoreResolver resolver = new DefaultScoreResolver(opScores); final int score = resolver.getScore(op1); assertEquals(2, score); }
@Test public void shouldGetScoreForOperationChain() { final GetAdjacentIds getAdjacentIds = mock(GetAdjacentIds.class); final GetElements getElements = mock(GetElements.class); final Limit limit = mock(Limit.class); final List<Operation> opList = Arrays.asList(getAdjacentIds, getElements, limit); final OperationChain opChain = mock(OperationChain.class); given(opChain.getOperations()).willReturn(opList); final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(Operation.class, 1); opScores.put(GetElements.class, 2); opScores.put(GetAdjacentIds.class, 3); opScores.put(Limit.class, 1); final DefaultScoreResolver resolver = new DefaultScoreResolver(opScores); final int score = resolver.getScore(opChain); assertEquals(6, score); }
@Test public void shouldGetScoreForNestedOperations() { final GetElements getElements = mock(GetElements.class); final GetWalks getWalks = mock(GetWalks.class); final GetAdjacentIds getAdjacentIds = mock(GetAdjacentIds.class); given(getWalks.getOperations()).willReturn( Collections.singletonList(new OperationChain<>(getAdjacentIds, getAdjacentIds))); final Limit limit = mock(Limit.class); final List<Operation> opList = Arrays.asList(getElements, getWalks, limit); final OperationChain opChain = mock(OperationChain.class); given(opChain.getOperations()).willReturn(opList); final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(Operation.class, 1); opScores.put(GetElements.class, 2); opScores.put(GetAdjacentIds.class, 2); opScores.put(Limit.class, 1); final DefaultScoreResolver resolver = new DefaultScoreResolver(opScores); final int score = resolver.getScore(opChain); assertEquals(7, score); }
@Test public void shouldGetOperationChainScore() throws OperationException { final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(); final OperationChain opChain = new OperationChain.Builder() .first(mock(GetAdjacentIds.class)) .then(mock(GetElements.class)) .build(); final Object result = scoreResolver.getScore(opChain); assertSame(2, result); }
@Test public void shouldGetScoreForOperationChainWithNestedOperationChain() throws OperationException { final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(); final OperationChain opChain = new OperationChain.Builder() .first(new OperationChain.Builder() .first(mock(GetAdjacentIds.class)) .then(mock(GetElements.class)) .build()) .then(mock(Limit.class)) .build(); final Object result = scoreResolver.getScore(opChain); assertSame(3, result); }
@Test public void shouldGetScoreForOperationChainContainingNamedOperation() throws OperationException { final ScoreResolver mockResolver = mock(NamedOperationScoreResolver.class); final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(Operation.class, 1); opScores.put(GetAdjacentIds.class, 2); opScores.put(GetElements.class, 3); opScores.put(Limit.class, 4); final Map<Class<? extends Operation>, ScoreResolver> resolvers = new HashMap<>(); final String opName = "basicOp"; final NamedOperation<Object, Object> namedOp = new Builder<>() .name(opName) .build(); resolvers.put(NamedOperation.class, mockResolver); given(mockResolver.getScore(eq(namedOp), any())).willReturn(5); final OperationChain opChain = new OperationChain.Builder() .first(new GetAdjacentIds()) .then(new GetElements()) .then(new Limit()) .then(new GetWalks.Builder() .addOperations(namedOp, new GetElements()) .build()) .build(); final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(opScores, resolvers); final Object result = scoreResolver.getScore(opChain); assertEquals(17, result); }
@Test public void shouldPreventInfiniteRecusion() throws OperationException { final Map<Class<? extends Operation>, ScoreResolver> resolvers = new HashMap<>(); resolvers.put(GetElements.class, new ScoreResolver() { @Override public Integer getScore(final Operation operation) { throw new IllegalArgumentException("defaultResolver is required"); } @Override public Integer getScore(final Operation operation, final ScoreResolver defaultScoreResolver) { return defaultScoreResolver.getScore(operation); } } ); final OperationChain opChain = new OperationChain.Builder() .first(new GetAdjacentIds()) .then(new GetElements()) .build(); final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(null, resolvers); final Object result = scoreResolver.getScore(opChain); assertEquals(2, result); }
@Test public void shouldGetScoreForOperationChainWhenNamedOperationScoreIsNull() throws OperationException { final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(Operation.class, 1); opScores.put(GetAdjacentIds.class, 2); opScores.put(GetElements.class, 1); opScores.put(Limit.class, 1); final Map<Class<? extends Operation>, ScoreResolver> resolvers = new HashMap<>(); final String opName = "basicOp"; final NamedOperation<Object, Object> namedOp = new Builder<>() .name(opName) .build(); final ScoreResolver mockResolver = mock(NamedOperationScoreResolver.class); resolvers.put(NamedOperation.class, mockResolver); given(mockResolver.getScore(eq(namedOp), any())).willReturn(null); final OperationChain opChain = new OperationChain.Builder() .first(new GetAdjacentIds()) .then(new GetElements()) .then(new Limit()) .then(namedOp) .build(); final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(opScores, resolvers); final Object result = scoreResolver.getScore(opChain); assertEquals(5, result); }
@Test public void shouldGetScoreForOperationChainWithMultipleScoreResolvers() throws OperationException { final Map<Class<? extends Operation>, ScoreResolver> resolvers = new HashMap<>(); final ScoreResolver mockResolver = mock(NamedOperationScoreResolver.class); final ScoreResolver mockResolver1 = mock(DefaultScoreResolver.class); final GetElements op1 = new GetElements(); final AddElements op2 = new AddElements(); final Map<Class<? extends Operation>, Integer> opScores = new LinkedHashMap<>(); opScores.put(GetElements.class, 2); final String opName = "namedOp"; final NamedOperation<Iterable<? extends Element>, Iterable<? extends Element>> namedOp = mock(NamedOperation.class); namedOp.setOperationName(opName); resolvers.put(namedOp.getClass(), mockResolver); resolvers.put(op2.getClass(), mockResolver1); given(mockResolver.getScore(eq(namedOp), any())).willReturn(3); given(mockResolver1.getScore(eq(op2), any())).willReturn(5); final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(opScores, resolvers); final OperationChain opChain = new OperationChain.Builder() .first(op1) .then(op2) .then(namedOp) .build(); final Object result = scoreResolver.getScore(opChain); assertEquals(10, result); }
@Test public void shouldGetScoreForNestedOperationWithNullOperationList() throws OperationException { final GetElements op1 = mock(GetElements.class); final AddElements op2 = mock(AddElements.class); final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(); final OperationChain opChain = new OperationChain.Builder() .first(op1) .then(op2) .then(new OperationChain((List) null)) .build(); final Object result = scoreResolver.getScore(opChain); assertEquals(2, result); }
@Test public void shouldReturnZeroForANullOperationChain() throws OperationException { final DefaultScoreResolver scoreResolver = new DefaultScoreResolver(); final OperationChain opChain = null; final Object result = scoreResolver.getScore(opChain); assertEquals(0, result); }