List<Input> makeInputs(String inputsStr) { List<Input> result = new LinkedList<>(); for (String inputStr : inputsStr.split(",")) { inputsStr = inputsStr.trim(); if (inputStr.length() > 0) { List<querqy.rewrite.commonrules.model.Term> terms = new LinkedList<>(); for (String termStr : inputStr.split("\\s+")) { if (termStr.length() > 0) { terms.add(new querqy.rewrite.commonrules.model.Term(termStr.toCharArray(), 0, termStr.length(), null)); } } if (!terms.isEmpty()) { result.add(new Input(terms)); } } } return result; }
@Test public void testGetInputSequencesForSingleTermWithFieldName() { char[] s1 = "test".toCharArray(); Term term1 = new Term(s1, 0, s1.length, Arrays.asList("name1")); Input input = new Input(Arrays.asList(term1), false, false); List<ComparableCharSequence> sequences = input.getInputSequences(false); assertNotNull(sequences); assertEquals(1, sequences.size()); ComparableCharSequence seq = sequences.get(0); assertNotNull(seq); assertEquals(0, seq.compareTo("name1:test")); }
@Override public void addRule(Input input, Instructions instructions) { List<Term> inputTerms = input.getInputTerms(); Term lastTerm = input.inputTerms.get(input.inputTerms.size() -1); boolean isPrefix = lastTerm instanceof PrefixTerm; for (ComparableCharSequence seq : input.getInputSequences(ignoreCase)) {
@Test public void testThatWildcardCanBeCombinedWithLeftBoundary() throws Exception { Object parseResult = LineParser.parseInput(LineParser.BOUNDARY + "a" + LineParser.WILDCARD); assertTrue(parseResult instanceof Input); Input input = (Input) parseResult; assertTrue(input.requiresLeftBoundary()); assertFalse(input.requiresRightBoundary()); }
return new DeleteInstruction(previousInput.getInputTerms()); return new DeleteInstruction(previousInput.getInputTerms()); List<Term> inputTerms = previousInput.getInputTerms(); for (Term term: deleteTerms) { if (term.findFirstMatch(inputTerms) == null) {
public List<ComparableCharSequence> getInputSequences(boolean lowerCaseValues) { if (inputTerms.size() == 1) { return inputTerms.get(0).getCharSequences(lowerCaseValues); } LinkedList<List<ComparableCharSequence>> slots = new LinkedList<>(); for (Term inputTerm : inputTerms) { slots.add(inputTerm.getCharSequences(lowerCaseValues)); } List<ComparableCharSequence> seqs = new LinkedList<>(); collectTails(new LinkedList<ComparableCharSequence>(), slots, seqs); return seqs; }
@Test public void testThatDeleteIsAppliedToMultiTermWildcardInput() throws Exception { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); Input input = (Input) LineParser.parseInput("ab k*"); DeleteInstruction deleteInstruction = new DeleteInstruction(input.getInputTerms()); builder.addRule(input, new Instructions(Collections.singletonList((Instruction) deleteInstruction))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery query = makeQuery("x ab klm"); Query rewritten = (Query) rewriter.rewrite(query, EMPTY_CONTEXT).getUserQuery(); assertThat(rewritten, bq( dmq( term("x") ) )); }
@Test public void testThatBoundariesAreParsedInInput() throws Exception { Object parseResult = LineParser.parseInput(LineParser.BOUNDARY + "a" + LineParser.BOUNDARY); assertTrue(parseResult instanceof Input); Input input = (Input) parseResult; assertTrue(input.requiresLeftBoundary()); assertTrue(input.requiresRightBoundary()); }
void collectTails(List<ComparableCharSequence> prefix, List<List<ComparableCharSequence>> tailSlots, List<ComparableCharSequence> result) { if (tailSlots.size() == 1) { for (ComparableCharSequence sequence : tailSlots.get(0)) { List<ComparableCharSequence> combined = new LinkedList<>(prefix); combined.add(sequence); result.add(new CompoundCharSequence(" ", combined)); } } else { List<List<ComparableCharSequence>> newTail = tailSlots.subList(1, tailSlots.size()); for (ComparableCharSequence sequence : tailSlots.get(0)) { List<ComparableCharSequence> newPrefix = new LinkedList<>(prefix); newPrefix.add(sequence); collectTails(newPrefix, newTail, result); } } }
@SuppressWarnings("unchecked") public static Object parseInput(String s) { boolean requiresLeftBoundary = false; boolean requiresRightBoundary = false; s = s.trim(); if (s.length() > 0 && s.charAt(0) == BOUNDARY) { requiresLeftBoundary = true; s = s.substring(1).trim(); } if (s.length() > 0 && s.charAt(s.length() - 1) == BOUNDARY) { requiresRightBoundary = true; s = s.substring(0, s.length() - 1).trim(); } int pos = s.indexOf('*'); if (pos > -1) { if (pos < (s.length() -1)) { return new ValidationError(WILDCARD + " is only allowed at the end of the input: " + s); } else if (requiresRightBoundary) { return new ValidationError(WILDCARD + " cannot be combined with right boundary"); } } Object expr = parseTermExpression(s); return (expr instanceof ValidationError) ? expr : new Input((List<Term>) expr, requiresLeftBoundary, requiresRightBoundary); }
@Test public void testGetInputSequencesForSingleTermWithoutFieldName() { char[] s1 = "test".toCharArray(); Term term1 = new Term(s1, 0, s1.length, null); Input input = new Input(Arrays.asList(term1), false, false); List<ComparableCharSequence> sequences = input.getInputSequences(false); assertNotNull(sequences); assertEquals(1, sequences.size()); ComparableCharSequence seq = sequences.get(0); assertNotNull(seq); assertEquals(0, seq.compareTo("test")); }
@Test public void testThatDeleteIsAppliedToWildcardInput() throws Exception { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); Input input = (Input) LineParser.parseInput("k*"); DeleteInstruction deleteInstruction = new DeleteInstruction(input.getInputTerms()); builder.addRule(input, new Instructions(Collections.singletonList((Instruction) deleteInstruction))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery query = makeQuery("x klm"); Query rewritten = (Query) rewriter.rewrite(query, EMPTY_CONTEXT).getUserQuery(); assertThat(rewritten, bq( dmq( term("x") ) )); }
@Test public void testThatBoundariesAreParsedInOtherwiseEmptyInput() throws Exception { Object parseResult = LineParser.parseInput(LineParser.BOUNDARY + "" + LineParser.BOUNDARY); assertTrue(parseResult instanceof Input); Input input = (Input) parseResult; assertTrue(input.requiresLeftBoundary()); assertTrue(input.requiresRightBoundary()); }
@SuppressWarnings("unchecked") @Test public void testThatSingleDecorationIsEmitted() { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); DecorateInstruction deco = new DecorateInstruction("deco1"); builder.addRule(new Input(Arrays.asList(mkTerm("x")), false, false), new Instructions(Arrays.asList((Instruction) deco))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery query = makeQuery("a x"); Map<String, Object> context = new HashMap<>(); rewriter.rewrite(query, context); assertThat((Set<Object>)context.get(DecorateInstruction.CONTEXT_KEY), contains( equalTo((Object) "deco1") )); }
@Test public void testGetInputSequencesForTermsWithAndWithoutFieldNames() { char[] s1 = "test".toCharArray(); Term term1 = new Term(s1, 0, s1.length, Arrays.asList("name1", "name2")); char[] s2 = "test2".toCharArray(); Term term2 = new Term(s2, 0, s2.length, null); Input input = new Input(Arrays.asList(term1, term2), false, false); List<ComparableCharSequence> sequences = input.getInputSequences(false); assertNotNull(sequences); assertEquals(2, sequences.size()); ComparableCharSequence seq = sequences.get(0); assertNotNull(seq); assertEquals("name1:test test2", seq.toString()); seq = sequences.get(1); assertNotNull(seq); assertEquals("name2:test test2", seq.toString()); }
DeleteInstruction deleteInstruction = new DeleteInstruction(input.getInputTerms());
@Test public void testActionsAreLoggedInContext() { RulesCollectionBuilder builder = new TrieMapRulesCollectionBuilder(false); SynonymInstruction synInstructionA = new SynonymInstruction(Arrays.asList(mkTerm("aSynonym"))); SynonymInstruction synInstructionB = new SynonymInstruction(Arrays.asList(mkTerm("bSynonym"))); builder.addRule(new Input(Arrays.asList(mkTerm("a")), true, false), new Instructions(Arrays.asList((Instruction) synInstructionA))); builder.addRule(new Input(Arrays.asList(mkTerm("b")), true, false), new Instructions(Arrays.asList((Instruction) synInstructionB))); RulesCollection rules = builder.build(); CommonRulesRewriter rewriter = new CommonRulesRewriter(rules); ExpandedQuery query = makeQuery("a b"); Map<String, Object> context = new HashMap<>(); Query rewritten = (Query) rewriter.rewrite(query, context).getUserQuery(); assertThat(rewritten, bq( dmq( term("a", false), term("aSynonym", true) ), dmq( term("b", false) ) )); assertThat(context.get(CommonRulesRewriter.CONTEXT_KEY_DEBUG_DATA), is(nullValue())); context.put(CommonRulesRewriter.CONTEXT_KEY_DEBUG_ENABLED, true); rewriter.rewrite(query, context).getUserQuery(); assertThat(context.containsKey(CommonRulesRewriter.CONTEXT_KEY_DEBUG_DATA), is(true)); assertThat(context.get(CommonRulesRewriter.CONTEXT_KEY_DEBUG_DATA).toString(), containsString(synInstructionA.toString())); assertThat(context.get(CommonRulesRewriter.CONTEXT_KEY_DEBUG_DATA).toString(), not(containsString(synInstructionB.toString()))); }
@Test public void testGetInputSequencesForTermsWithoutFieldName() { char[] s1 = "test".toCharArray(); Term term1 = new Term(s1, 0, s1.length, null); char[] s2 = "test2".toCharArray(); Term term2 = new Term(s2, 0, s2.length, null); Input input = new Input(Arrays.asList(term1, term2), false, false); List<ComparableCharSequence> sequences = input.getInputSequences(false); assertNotNull(sequences); assertEquals(1, sequences.size()); ComparableCharSequence seq = sequences.get(0); assertNotNull(seq); assertEquals(0, seq.compareTo("test test2")); }
DecorateInstruction deco3 = new DecorateInstruction("deco3"); builder.addRule(new Input(Arrays.asList(mkTerm("x")), false, false), new Instructions(Arrays.asList((Instruction) deco1, (Instruction) deco2))); builder.addRule(new Input(Arrays.asList(mkTerm("a")), false, false), new Instructions(Arrays.asList((Instruction) deco3)));
@Test public void testGetInputSequencesForSingleTermWithFieldNames() { char[] s1 = "test".toCharArray(); Term term1 = new Term(s1, 0, s1.length, Arrays.asList("name1", "name2")); Input input = new Input(Arrays.asList(term1), false, false); List<ComparableCharSequence> sequences = input.getInputSequences(false); assertNotNull(sequences); assertEquals(2, sequences.size()); ComparableCharSequence seq = sequences.get(0); assertNotNull(seq); assertEquals(0, seq.compareTo("name1:test")); seq = sequences.get(1); assertNotNull(seq); assertEquals(0, seq.compareTo("name2:test")); }