summaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java125
1 files changed, 125 insertions, 0 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java
new file mode 100644
index 00000000000..855a8b802ba
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/prelude/semantics/rule/ConditionReference.java
@@ -0,0 +1,125 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.prelude.semantics.rule;
+
+import com.yahoo.prelude.query.TermItem;
+import com.yahoo.prelude.querytransform.PhraseMatcher;
+import com.yahoo.prelude.semantics.RuleBase;
+import com.yahoo.prelude.semantics.RuleBaseException;
+import com.yahoo.prelude.semantics.engine.Choicepoint;
+import com.yahoo.prelude.semantics.engine.EvaluationException;
+import com.yahoo.prelude.semantics.engine.FlattenedItem;
+import com.yahoo.prelude.semantics.engine.RuleEvaluation;
+import com.yahoo.protect.Validator;
+
+import java.util.Map;
+
+/**
+ * A reference to a named condition
+ *
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon S Bratseth</a>
+ */
+public class ConditionReference extends Condition {
+
+ /** The name of the referenced rule */
+ private String conditionName;
+
+ /**
+ * The actual condition references by this, or null if not initialized or not found,
+ * or if this is really an automata reference
+ */
+ private NamedCondition namedCondition;
+
+ /**
+ * True if this condition should be looked up in the automata
+ * annotations of the item instead of by reference to another item
+ */
+ private boolean automataLookup=false;
+
+ public ConditionReference(String conditionName) {
+ this(null,conditionName);
+ }
+
+ public ConditionReference(String label,String conditionName) {
+ super(label);
+ Validator.ensureNotNull("Name of referenced condition",conditionName);
+ this.conditionName=conditionName;
+ setContextName(conditionName);
+ }
+
+ /** Returns the name of the referenced rule, never null */
+ public String getConditionName() { return conditionName; }
+
+ public void setConditionName(String name) { this.conditionName=name; }
+
+ public boolean doesMatch(RuleEvaluation e) {
+ if (automataLookup) return automataMatch(e);
+
+ if (namedCondition==null)
+ throw new EvaluationException("Condition reference '" + conditionName +
+ "' not found or not initialized");
+
+ return namedCondition.matches(e);
+ }
+
+ private boolean automataMatch(RuleEvaluation e) {
+ FlattenedItem current=e.currentItem();
+ if (current==null) return false;
+
+ Object annotation=current.getItem().getAnnotation(conditionName);
+ if (annotation==null) return false;
+ if (! (annotation instanceof PhraseMatcher.Phrase)) return false;
+
+ PhraseMatcher.Phrase phrase=(PhraseMatcher.Phrase)annotation;
+
+ Choicepoint choicePoint=e.getChoicepoint(this,true);
+ boolean matches=automataMatchPhrase(phrase,e);
+
+ if (!matches && e.isInNegation()) { // TODO: Temporary hack! Works for single items only
+ e.addMatch(current,null);
+ }
+
+ if ((!matches && !e.isInNegation() || (matches && e.isInNegation())))
+ choicePoint.backtrackPosition();
+
+ return matches;
+ }
+
+ private boolean automataMatchPhrase(PhraseMatcher.Phrase phrase,RuleEvaluation e) {
+ for (PhraseMatcher.Phrase.MatchIterator i=phrase.itemIterator(); i.hasNext(); ) {
+ i.next();
+ FlattenedItem current=e.currentItem();
+ if (current==null) return false;
+ if (!labelMatches(e.currentItem().getItem(),e)) return false;
+ if (!e.isInNegation())
+ e.addMatch(current,i.getReplace());
+ e.next();
+ }
+ if (phrase.getLength()>phrase.getBackedLength()) return false; // The underlying composite item has changed
+ return true;
+ }
+
+ public void makeReferences(RuleBase ruleBase) {
+ namedCondition=ruleBase.getCondition(conditionName);
+ if (namedCondition==null) { // Then this may reference some automata value, if we have an automata
+ if (ruleBase.usesAutomata())
+ automataLookup=true;
+ else
+ throw new RuleBaseException("Referenced condition '" + conditionName +
+ "' does not exist in " + ruleBase);
+ }
+ }
+
+ protected boolean hasOpenChoicepoint(RuleEvaluation e) {
+ if (namedCondition==null) return false;
+ return namedCondition.getCondition().hasOpenChoicepoint(e);
+ }
+
+ protected boolean isDefaultContextName() {
+ return getContextName()==null || getContextName().equals(conditionName);
+ }
+
+ protected String toInnerString() {
+ return "[" + conditionName + "]";
+ }
+
+}