SelectDataStoreOperation implements DataStoreOperation<List<E>, K, E> { @Override public List<E> execute(DataStore<K, E> store, RepositoryConfiguration configuration, Invocation invocation) { log.info("Selecting the data according to the provided selection descriptor: " + descriptor); final List<E> selection = new LinkedList<>(); final Collection<E> all = new LinkedList<>(store.retrieveAll()); for (E entity : all) { if (descriptor.matches(entity, invocation)) { selection.add(entity); } } log.info("Matched " + selection.size() + " items from the data store"); if (descriptor.isDistinct()) { final Set<E> distinctValues = new HashSet<>(selection); selection.clear(); selection.addAll(distinctValues); log.info("After clearing up duplicates, " + selection.size() + " items remained"); } final Sort sort = descriptor.getSort(invocation); final Page page = descriptor.getPage(invocation); if (sort != null) { log.info("Sorting the selected items according to the provided ordering"); PropertyComparator.sort(selection, sort); } if (page != null) { log.info("We need to paginate the selection to fit the selection criteria"); int start = page.getPageSize() * page.getPageNumber(); int finish = Math.min(start + page.getPageSize(), selection.size()); if (start > selection.size()) { selection.clear(); } else { final List<E> view = new ArrayList<>(selection.subList(start, finish)); selection.clear(); selection.addAll(view); } } if (descriptor.getLimit() > 0) { log.info("Going to limit the result to " + descriptor.getLimit() + " items"); final List<E> view = new ArrayList<>(selection.subList(0, Math.min(selection.size(), descriptor.getLimit()))); selection.clear(); selection.addAll(view); } return selection; } SelectDataStoreOperation(QueryDescriptor descriptor); QueryDescriptor getDescriptor(); @Override List<E> execute(DataStore<K, E> store, RepositoryConfiguration configuration, Invocation invocation); @Override String toString();  }
@Test public void testSimpleSelection() throws Exception { final List<List<Parameter>> branches = new ArrayList<>(); final DefaultOperatorContext operatorContext = new DefaultOperatorContext(); branches.add(Arrays.asList( new ImmutableParameter("firstName", Collections.emptySet(), new int[]{0}, operatorContext.getBySuffix("Is")), new ImmutableParameter("lastName", Collections.emptySet(), new int[]{1}, operatorContext.getBySuffix("Is")) )); branches.add(Collections.singletonList( new ImmutableParameter("address.city", Collections.emptySet(), new int[]{2}, operatorContext.getBySuffix("Is")) )); branches.add(Collections.singletonList( new ImmutableParameter("age", Collections.emptySet(), new int[]{3}, operatorContext.getBySuffix("GreaterThan")) )); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, 0, null, null, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operation = new SelectDataStoreOperation<>(descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class .getMethod("findByFirstNameAndLastNameOrAddressCityOrAgeGreaterThan", String.class, String.class, String.class, Integer.class), new Object[]{"Milad", "Naseri", "Tabriz", 100})); assertThat(selected, is(notNullValue())); assertThat(selected, hasSize(2)); assertThat(selected.get(0).getId(), isIn(Arrays.asList("k1", "k3"))); assertThat(selected.get(1).getId(), isIn(Arrays.asList("k1", "k3"))); }
@Test public void testSorting() throws Exception { final ImmutableOrder first = new ImmutableOrder(SortDirection.ASCENDING, "address.city", NullHandling.DEFAULT); final ImmutableOrder second = new ImmutableOrder(SortDirection.ASCENDING, "lastName", NullHandling.DEFAULT); final ImmutableSort sort = new ImmutableSort(Arrays.asList(first, second)); final WrappedSortParameterExtractor sortExtractor = new WrappedSortParameterExtractor(sort); final List<List<Parameter>> branches = new ArrayList<>(); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, 0, null, sortExtractor, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operation = new SelectDataStoreOperation<>(descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll"), new Object[]{})); assertThat(selected, hasSize(4)); assertThat(selected, containsInAnyOrder(dataStore.retrieveAll().toArray())); assertThat(selected.get(0).getId(), is("k4")); assertThat(selected.get(1).getId(), is("k3")); assertThat(selected.get(2).getId(), is("k2")); assertThat(selected.get(3).getId(), is("k1")); }
@Test public void testPagingWhenPageStartIsBeyondSelection() throws Exception { final List<List<Parameter>> branches = new ArrayList<>(); final PageParameterExtractor pageExtractor = new PageablePageParameterExtractor(0); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, 0, pageExtractor, null, branches, null, null); final SelectDataStoreOperation<String, Person> operation = new SelectDataStoreOperation<>(descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll", Pageable.class), new Object[]{PageRequest.of(2, 10)})); assertThat(selected, is(empty())); }
@Test public void testPagingWhenLastPageIsNotFull() throws Exception { final PageParameterExtractor pageExtractor = new PageablePageParameterExtractor(0); final List<List<Parameter>> branches = Collections.emptyList(); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, 0, pageExtractor, null, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operation = new SelectDataStoreOperation<>(descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll", Pageable.class), new Object[]{PageRequest.of(1, 3)})); assertThat(selected, hasSize(1)); }
@Test public void testLimitingTheResult() throws Exception { for (int limit = 1; limit < 10; limit++) { final List<List<Parameter>> branches = Collections.emptyList(); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, limit, null, null, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operation = new SelectDataStoreOperation<>( descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll"), new Object[]{})); assertThat(selected, hasSize(Math.min(limit, dataStore.retrieveAll().size()))); } }
@Test public void testLoadingDistinctValues() throws Exception { dataStore.save("k5", new Person().setId("k1")); final List<List<Parameter>> branches = Collections.emptyList(); final DefaultQueryDescriptor descriptor = new DefaultQueryDescriptor(false, null, 0, null, null, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operation = new SelectDataStoreOperation<>(descriptor); final List<Person> selected = operation.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll"), new Object[]{})); assertThat(selected, hasSize(5)); final DefaultQueryDescriptor descriptorDistinct = new DefaultQueryDescriptor(true, null, 0, null, null, branches, null, null); final DataStoreOperation<List<Person>, String, Person> operationDistinct = new SelectDataStoreOperation<>( descriptorDistinct); final List<Person> selectedDistinct = operationDistinct.execute(dataStore, null, new ImmutableInvocation( RepositoryWithValidMethods.class.getMethod("findAll"), new Object[]{})); assertThat(selectedDistinct, hasSize(4)); }