aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java')
-rw-r--r--container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java87
1 files changed, 87 insertions, 0 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java
new file mode 100644
index 00000000000..8cb6bf34021
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/search/query/profile/QueryProfileVisitor.java
@@ -0,0 +1,87 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.query.profile;
+
+/**
+ * Instances of this is used to visit nodes in a graph of query profiles
+ *
+ * <code>
+ * Visitor are called in the following sequence on each query profile:
+ * enter=enter(referenceName);
+ * onQueryProfile(this)
+ * if (enter) {
+ * getLocalKey()
+ * ...calls on nested content found in variants, this and inherited, in that order
+ * leave(referenceName)
+ * }
+ *
+ * The first enter call will be on the root node, which has an empt reference name.
+ * </code>
+ *
+ * @author <a href="mailto:bratseth@yahoo-inc.com">Jon Bratseth</a>
+ */
+abstract class QueryProfileVisitor {
+
+ /**
+ * Called when a new <b>nested</b> profile in the graph is entered.
+ * This default implementation does nothing but returning true.
+ * If the node is entered (if true is returned from this), a corresponding {@link #leave(String)} call will happen
+ * later.
+ *
+ * @param name the name this profile is nested as, or the empty string if we are entering the root profile
+ * @return whether we should visit the content of this node or not
+ */
+ public boolean enter(String name) { return true; }
+
+ /**
+ * Called when the last {@link #enter(String) entered} nested profile is left.
+ * That is: One leave call is made for each enter call which returns true,
+ * but due to nesting those calls are not necessarily alternating.
+ * This default implementation does nothing.
+ */
+ public void leave(String name) { }
+
+ /**
+ * Called when a value (not a query profile) is encountered.
+ *
+ * @param localName the local name of this value (the full name, if needed, must be reconstructed
+ * by the information given by the history of {@link #enter(String)} and {@link #leave(String)} calls
+ * @param value the value
+ * @param binding the binding this holds for
+ * @param owner the query profile having this value, or null only when profile is the root profile
+ */
+ public abstract void onValue(String localName, Object value, DimensionBinding binding, QueryProfile owner);
+
+ /**
+ * Called when a query profile is encountered.
+ *
+ * @param profile the query profile reference encountered
+ * @param binding the binding this holds for
+ * @param owner the profile making this reference, or null only when profile is the root profile
+ */
+ public abstract void onQueryProfile(QueryProfile profile, DimensionBinding binding, QueryProfile owner);
+
+ /** Returns whether this visitor is done visiting what it needed to visit at this point */
+ public abstract boolean isDone();
+
+ /** Returns whether we should, at this point, visit inherited profiles. This default implementation returns true */
+ public boolean visitInherited() { return true; }
+
+ /**
+ * Returns the current local key which should be visited in the last {@link #enter(String) entered} sub-profile
+ * (or in the top level profile if none is entered), or null to visit all content
+ */
+ public abstract String getLocalKey();
+
+ /** Calls onValue or onQueryProfile on this and visits the content if it's a profile */
+ final void acceptValue(String key, Object value, DimensionBinding dimensionBinding, QueryProfile owner) {
+ if (value==null) return;
+ if (value instanceof QueryProfile) {
+ QueryProfile queryProfileValue=(QueryProfile)value;
+ queryProfileValue.acceptAndEnter(key, this, dimensionBinding.createFor(queryProfileValue.getDimensions()), owner);
+ }
+ else {
+ onValue(key, value, dimensionBinding, owner);
+ }
+ }
+
+}