Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

Expand All @@ -31,6 +33,8 @@
import org.jetbrains.annotations.NotNull;

public class ListQuery {
private static final Pattern PAGE_CLAUSE_PATTERN = Pattern.compile("(?i)\\bpage\\s+(\\d+)\\b");

boolean allContent;
Long max;
Long page;
Expand All @@ -53,6 +57,14 @@ public void setMax(Long max) {
this.max = max;
}

public Long getPage() {
return page;
}

public void setPage(Long page) {
this.page = page;
}

public void setSearch(Map<String, String> search) {
this.search = search;
}
Expand Down Expand Up @@ -108,50 +120,33 @@ public static ListQuery fromRequest(HttpServletRequest request) {
query.setFollow(follow);
Map<String, String> searchItems = getSearchMap(request.getParameter("search"));
if (!searchItems.isEmpty()) {
try {
query.setMax(Long.parseLong(searchItems.get("page")));
} catch (NumberFormatException e) {
// Ignore invalid page and keep default null value.
String pageValue = searchItems.get("page");
if (StringUtils.isNotBlank(pageValue)) {
try {
query.setPage(Long.parseLong(pageValue));
} catch (NumberFormatException e) {
// Ignore invalid page and keep default null value.
}
}
query.setSearch(searchItems);
}

return query;
}

// Parse search clause. Only keep items which use simple '=' operator, and ignore others. For example:
// name=myvm and status=up --> {name=myvm, status=up}
// name=myvm and status!=down --> {name=myvm} (ignore status!=down because it uses '!=' operator)
// Parse search clause. For now, only extract the oVirt paging clause.
// Examples:
// page 3 --> {page=3}
// sortby name page 2 --> {page=2}
@NotNull
private static Map<String, String> getSearchMap(String searchClause) {
Map<String, String> searchItems = new LinkedHashMap<>();
if (StringUtils.isBlank(searchClause)) {
return searchItems;
}
String[] terms = searchClause.trim().split("(?i)\\s+and\\s+");
for (String term : terms) {
if (term == null) {
continue;
}
String trimmedTerm = term.trim();
if (trimmedTerm.isEmpty()) {
continue;
}

int eqIdx = trimmedTerm.indexOf('=');
if (eqIdx <= 0 || eqIdx != trimmedTerm.lastIndexOf('=')) {
continue;
}
char prev = trimmedTerm.charAt(eqIdx - 1);
if (prev == '!' || prev == '<' || prev == '>') {
continue;
}

String key = trimmedTerm.substring(0, eqIdx).trim();
String value = trimmedTerm.substring(eqIdx + 1).trim();
if (!key.isEmpty() && !value.isEmpty()) {
searchItems.put(key, value);
}
Matcher matcher = PAGE_CLAUSE_PATTERN.matcher(searchClause);
if (matcher.find()) {
searchItems.put("page", matcher.group(1));
}
return searchItems;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,18 @@ public void testFromRequest_ParsesAllContentMaxAndFollow() {
}

@Test
public void testFromRequest_SearchParserIgnoresNonEqualsAndUsesPageValueAsMaxCurrentBehavior() {
public void testFromRequest_SearchParserExtractsPageOnly() {
final HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"name=vm and page=3 and status!=down and x>=1"}));
when(request.getParameterMap()).thenReturn(Map.of("search", new String[]{"sortby name page 3"}));
when(request.getParameter("all_content")).thenReturn(null);
when(request.getParameter("max")).thenReturn(null);
when(request.getParameter("follow")).thenReturn(null);
when(request.getParameter("search")).thenReturn("name=vm and page=3 and status!=down and x>=1");
when(request.getParameter("search")).thenReturn("sortby name page 3");

final ListQuery query = ListQuery.fromRequest(request);

// Document existing behavior: when search contains page=..., max is set from it.
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getLimit());
// Only page key is extracted from search clause in oVirt format "page N"
org.junit.Assert.assertEquals(Long.valueOf(3L), query.getPage());
}

@Test
Expand Down
Loading