group proposal as if they were hierarchical
We interpret dots ('.') as hierarchy delimiter in.
That way we can reduce the number of proposed values
and show only those for the next level.
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
package org.lucares.pdb.datastore.lang;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class CandidateGrouper {
|
||||||
|
public SortedSet<String> group(final Collection<String> values, final String queryWithCaretMarker) {
|
||||||
|
|
||||||
|
final TreeSet<String> result = new TreeSet<>();
|
||||||
|
final int numDotsInValue = countDotsInValue(queryWithCaretMarker);
|
||||||
|
|
||||||
|
for (final String value : values) {
|
||||||
|
// keep everyting up to the (numDotsInValue+1)-th
|
||||||
|
final String[] token = value.split(Pattern.quote("."));
|
||||||
|
final List<String> tokenlist = new ArrayList<>(Arrays.asList(token));
|
||||||
|
final List<String> prefix = tokenlist.subList(0, numDotsInValue + 1);
|
||||||
|
String shortenedValue = String.join(".", prefix);
|
||||||
|
if (tokenlist.size() > numDotsInValue + 1) {
|
||||||
|
shortenedValue += ".";
|
||||||
|
}
|
||||||
|
result.add(shortenedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countDotsInValue(final String queryWithCaretMarker) {
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
int index = queryWithCaretMarker.indexOf(NewProposerParser.CARET_MARKER) - 1;
|
||||||
|
final String delimiter = " (),=!";
|
||||||
|
|
||||||
|
while (index >= 0) {
|
||||||
|
final char c = queryWithCaretMarker.charAt(index);
|
||||||
|
if (delimiter.indexOf(c) >= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == '.') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -167,8 +167,11 @@ public class NewProposerParser {
|
|||||||
final SortedSet<String> candidateValues = normalizedExpression
|
final SortedSet<String> candidateValues = normalizedExpression
|
||||||
.visit(new FindValuesForQueryCompletion(queryCompletionIndex));
|
.visit(new FindValuesForQueryCompletion(queryCompletionIndex));
|
||||||
|
|
||||||
|
final SortedSet<String> candidateValuesCutAtDots = cutAtDots(candidateValues, queryWithCaretMarker);
|
||||||
|
|
||||||
// translate the candidate values to proposals
|
// translate the candidate values to proposals
|
||||||
final List<Proposal> proposals = generateProposals(queryWithCaretMarker, expression, candidateValues);
|
final List<Proposal> proposals = generateProposals(queryWithCaretMarker, expression,
|
||||||
|
candidateValuesCutAtDots);
|
||||||
|
|
||||||
return proposals;
|
return proposals;
|
||||||
} catch (final SyntaxException e) {
|
} catch (final SyntaxException e) {
|
||||||
@@ -178,6 +181,11 @@ public class NewProposerParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SortedSet<String> cutAtDots(final SortedSet<String> candidateValues, final String queryWithCaretMarker) {
|
||||||
|
final CandidateGrouper grouper = new CandidateGrouper();
|
||||||
|
return grouper.group(candidateValues, queryWithCaretMarker);
|
||||||
|
}
|
||||||
|
|
||||||
private List<Proposal> generateProposals(final String queryWithCaretMarker, final Expression expression,
|
private List<Proposal> generateProposals(final String queryWithCaretMarker, final Expression expression,
|
||||||
final SortedSet<String> candidateValues) {
|
final SortedSet<String> candidateValues) {
|
||||||
final List<Proposal> proposals = new ArrayList<>();
|
final List<Proposal> proposals = new ArrayList<>();
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package org.lucares.pdb.datastore.lang;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public class CandidateGrouperTest {
|
||||||
|
|
||||||
|
@DataProvider
|
||||||
|
public Object[][] providerGroup() {
|
||||||
|
final List<Object[]> result = new ArrayList<>();
|
||||||
|
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.yy.BB", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = |", //
|
||||||
|
Set.of("aa.") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.yy.BB", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = a|", //
|
||||||
|
Set.of("aa.") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.yy.BB", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = aa|", //
|
||||||
|
Set.of("aa.") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.yy.BB", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = aa.|", //
|
||||||
|
Set.of("aa.xx.", "aa.yy.") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = aa.x|", //
|
||||||
|
Set.of("aa.xx.") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.xx.BB", "aa.xx.AA.YY"), //
|
||||||
|
"name = aa.xx.|", //
|
||||||
|
Set.of("aa.xx.AA.", "aa.xx.BB") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.xx.AA.YY"), //
|
||||||
|
"name = aa.xx.AA.|", //
|
||||||
|
Set.of("aa.xx.AA.XX", "aa.xx.AA.YY") });
|
||||||
|
result.add(new Object[] { //
|
||||||
|
Set.of("XX.YY.ZZ", "XX.YY"), //
|
||||||
|
"name = XX.Y|", //
|
||||||
|
Set.of("XX.YY.", "XX.YY") });
|
||||||
|
|
||||||
|
return result.toArray(new Object[0][]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "providerGroup")
|
||||||
|
public void testGroup(final Set<String> values, final String queryWithCaretMarker, final Set<String> expected) {
|
||||||
|
final CandidateGrouper grouper = new CandidateGrouper();
|
||||||
|
|
||||||
|
final String query = queryWithCaretMarker.replace("|", NewProposerParser.CARET_MARKER);
|
||||||
|
|
||||||
|
final SortedSet<String> actual = grouper.group(values, query);
|
||||||
|
|
||||||
|
Assert.assertEquals(actual, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user