1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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 bratseth
*/
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);
}
}
}
|